Topic: Lifetime of temporaries (non expert Q)
Author: jarausch@igpm.rwth-aachen.de (Helmut Jarausch)
Date: 4 Jan 1994 14:14:45 GMT Raw View
Please help! I am not an expert in this group
(On my compiler (SGI based on cfront3.0.?)
The following two versions of function `main'
use different amount of memory
void main()
{ VDim=3;
Temp_Vector U(VDim), V(VDim),W(VDim);
cout << "-------------------" << endl;
W= U+V;
cout << "-------------------" << endl;
W= U+V;
cout << "-------------------" << endl;
}
void main()
{ VDim=3;
Temp_Vector U(VDim), V(VDim),W(VDim);
for ( int i=0; i < 2; i++ )
{ cout << "-------------------" << endl;
W= U+V;
}
}
The temporary for the sum is constructed twice in the first case
and both are destructed only at the end of function main.
In the second case the temporary is constructed each time
before computing the sum and destructed just after the assignment.
So this version uses less memory.
Is the behaviour of the first version the current and forthcoming
standard? If so, how can I avoid the construction of too many
temporaries - only putting each assignment into an extra block?
Thanks for repsonding,
Helmut Jarausch
Institute of Technology
RWTH-Aachen, Germany
P.S.
Definition of Temp_Vector:
//const int VDim= 3;
int VDim;
class Temp_Vector
{ int *V;
int Dim;
public:
Temp_Vector( int D )
{ Dim= D; V= new int[D+1];
V[0]=1; // reference count
cout << "standard constructor " << hex << (int) V << endl;
}
Temp_Vector( const Temp_Vector& TV )
{ Dim= TV.Dim;
V= TV.V;
V[0]++;
cout << "copy constructor " << hex << (int) V
<< " Ref: " << V[0] << endl;
}
~Temp_Vector()
{
cout << "destructor for " << hex << (int) V
<< " Ref: " << V[0] << endl;
if ( --V[0] <= 0 ) delete[] V;
}
Temp_Vector& operator= ( const Temp_Vector& TV )
{ Dim= TV.Dim;
V[0]--;
V= TV.V;
V[0]++;
cout << "operator= for " << hex << (int) V
<< " Ref: " << V[0] << endl;
return *this;
}
friend Temp_Vector operator+( const Temp_Vector&, const Temp_Vector& );
};
Temp_Vector operator+( const Temp_Vector& A, const Temp_Vector& B )
{ Temp_Vector R(A.Dim);
cout << "op+ " << hex << (int)A.V << " + " << (int)B.V
<< " --> " << (int) R.V << endl;
if ( A.Dim != B.Dim )
{ cerr << "Dimension mismatch\n"; abort(); }
for (int i= 1; i <= A.Dim; i++) R.V[i]= A.V[i]+B.V[i];
return R;
}
OUTPUT: Version 1
standard constructor 1000b138
standard constructor 1000b558
standard constructor 1000b570
-------------------
standard constructor 1000b588
op+ 1000b138 + 1000b558 --> 1000b588
operator= for 1000b588 Ref: 2
-------------------
standard constructor 1000b5a0
op+ 1000b138 + 1000b558 --> 1000b5a0
operator= for 1000b5a0 Ref: 2
-------------------
destructor for 1000b5a0 Ref: 2
destructor for 1000b588 Ref: 1
destructor for 1000b5a0 Ref: 1
destructor for 1000b558 Ref: 1
destructor for 1000b138 Ref: 1
OUTPUT: Version 2
standard constructor 1000b138
standard constructor 1000b558
standard constructor 1000b570
-------------------
standard constructor 1000b588
op+ 1000b138 + 1000b558 --> 1000b588
operator= for 1000b588 Ref: 2
destructor for 1000b588 Ref: 2
-------------------
standard constructor 1000b5a0
op+ 1000b138 + 1000b558 --> 1000b5a0
operator= for 1000b5a0 Ref: 2
destructor for 1000b5a0 Ref: 2
-------------------
destructor for 1000b5a0 Ref: 1
destructor for 1000b558 Ref: 1
destructor for 1000b138 Ref: 1
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 4 Jan 1994 15:57:04 GMT Raw View
jarausch@igpm.rwth-aachen.de (Helmut Jarausch) writes:
>(On my compiler (SGI based on cfront3.0.?)
>The following two versions of function `main'
>use different amount of memory
>void main()
>{ VDim=3;
> Temp_Vector U(VDim), V(VDim),W(VDim);
> cout << "-------------------" << endl;
> W= U+V;
> cout << "-------------------" << endl;
> W= U+V;
> cout << "-------------------" << endl;
>}
>
>
>void main()
>{ VDim=3;
> Temp_Vector U(VDim), V(VDim),W(VDim);
> for ( int i=0; i < 2; i++ )
> { cout << "-------------------" << endl;
> W= U+V;
> }
>}
>
>The temporary for the sum is constructed twice in the first case
>and both are destructed only at the end of function main.
>
>In the second case the temporary is constructed each time
>before computing the sum and destructed just after the assignment.
>So this version uses less memory.
>
>Is the behaviour of the first version the current and forthcoming
>standard?
No. The standard specifies that temporaries should be destroyed
at the end of each full expression. Your Cfront-based compiler
is destroying them at the end of the enclosing scope, which
is OK according to the ARM, but is not OK according to the
most recent drafts of the committee's working paper.
>If so, how can I avoid the construction of too many
>temporaries - only putting each assignment into an extra block?
Yes, it's either that, or wait for a compiler which implements
the committee's new rules for destruction of temporaries.
--
Fergus Henderson | "People who brook no compromise in programming
| languages should program in lambda calculus or
fjh@munta.cs.mu.OZ.AU | machine language, depending." --Andrew Koenig.
Author: dag@control.lth.se (Dag Bruck)
Date: 4 Jan 1994 18:29:03 GMT Raw View
Current documents do not specify when temporaries are destroyed, so
destroying them at end-of-block is one correct behaviour.
The standards committee has a short while back decided that
temporaries shall be destroyed at the end of the greatest enclosing
expression, in your case:
W = U + V;
they will be destroyed at the semicolon (in both versions of your
program).
Unfortunately, it will take some time for the compiler vendors to
catch up and implemnent this rule.
-- Dag