For all my self-conscious file I was sure that temporary object will be destructed right after calculating expression that using this object will be computed. However, the following example illustrates that temporary objects lives a bit longer than expression:
In my assumptions this code should be incorrect and print something like the following: A::A(): hello, world A::operator(): hello, world ~A::A(): hello, world A::A(): world //here some error should occur or data should be incorrect ~A::A(): world
But in fact I see that first object (with "hello, world") is being destructed last: A::A(): hello, world A::operator(): hello, world A::A(): world ~A::A(): world ~A::A(): hello, world
Can anybody explain (or quote appropriate standard paragraph) this behaviour?
> For all my self-conscious file I was sure that temporary object will > be destructed right after calculating expression that using this > object will be computed.
mostly right.
> However, the following example illustrates > that temporary objects lives a bit longer than expression:
this doesn't seem really the case here...
[cut]
> A( A("hello, world")()+7 ); [cut]
> Can anybody explain (or quote appropriate standard paragraph) this > behaviour?
two temporary are being instantiated here, an external one (the one initialized with "world") and an internal one (initialised with "hello, world"). The lifetime rules are: a) the external object, being an unnamed object, is destroyed at the end of the full expression (the quoted one); b) the internal object, being a temporary bound to a reference that is the argument of a function call, is destroyed also the end of the full expression (§12.2.5) c) as of the standard (§12.2.5), "...the destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static or automatic storage duration (3.7.1, 3.7.2); that is, [...] if obj2 is an object with static or automatic storage duration created after the temporary is created, the temporary shall be destroyed after obj2 is destroyed", which means, when destructing the internal object, since the external one (obj2 in the standard wording) has been created after the internal, it has to be destroyed after.
> For all my self-conscious file I was sure that temporary object will > be destructed right after calculating expression that using this > object will be computed.
Hmm, not exactly.
To paraphrase Herb Sutter : "Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself".
So, in your example: A( A("hello, world")()+7 );
the temporary object is bind to const string& which is a const reference (of course :) and that will extend the life of the temporary.
> In my assumptions this code should be incorrect and print something > like the following: > A::A(): hello, world > A::operator(): hello, world > ~A::A(): hello, world > A::A(): world //here some error should occur or data should be > incorrect > ~A::A(): world
> But in fact I see that first object (with "hello, world") is being > destructed last: > A::A(): hello, world > A::operator(): hello, world > A::A(): world > ~A::A(): world > ~A::A(): hello, world
> Can anybody explain (or quote appropriate standard paragraph) this > behaviour?
The temporaries live till the end of the full expression. That's at the semicolon, in your example.
I don't know if there is a required order for the destruction of several temporaries here, but the reverse order of their construction is what is required elsewhere.
> For all my self-conscious file I was sure that temporary object will > be destructed right after calculating expression that using this > object will be computed. However, the following example illustrates > that temporary objects lives a bit longer than expression:
> In my assumptions this code should be incorrect and print something > like the following: > A::A(): hello, world > A::operator(): hello, world > ~A::A(): hello, world > A::A(): world //here some error should occur or data should be > incorrect > ~A::A(): world
> But in fact I see that first object (with "hello, world") is being > destructed last: > A::A(): hello, world > A::operator(): hello, world > A::A(): world > ~A::A(): world > ~A::A(): hello, world
> Can anybody explain (or quote appropriate standard paragraph) this > behaviour?
12.2[class.temporary]/3:
"Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created."
full-expression for your case is the whole statement up to the semicolon, so the inner temporary is not destroyed until then.
As for the order of destruction, the rule is the same as usual - objects are destructed in reverse order; whichever one was constructed last will be destructed first.
> For all my self-conscious file I was sure that temporary object will > be destructed right after calculating expression that using this > object will be computed. However, the following example illustrates > that temporary objects lives a bit longer than expression:
Yes, temporaries live till the end of the /full expression/ in which they were created. A /full expression/ is an expression that is not a part of a larger expression.
> In my assumptions this code should be incorrect and print something > like the following: > A::A(): hello, world > A::operator(): hello, world > ~A::A(): hello, world > A::A(): world //here some error should occur or data should be > incorrect > ~A::A(): world
> But in fact I see that first object (with "hello, world") is being > destructed last: > A::A(): hello, world > A::operator(): hello, world > A::A(): world > ~A::A(): world > ~A::A(): hello, world
> Can anybody explain (or quote appropriate standard paragraph) this > behaviour?
The standards paragraph is 12.2 [class.temporary]. It states that both A objects will persist until the end of the initialisation of the outer A, and that the two objects will be destructed in reverse order of their construction.
{ edits: 7 lines quoted sig removed. do not quote extraneous material. -mod }
On Mar 6, 8:59 pm, "Bo Persson" <b...@gmb.dk> wrote:
> The temporaries live till the end of the full expression. That's at > the semicolon, in your example.
> I don't know if there is a required order for the destruction of > several temporaries here, but the reverse order of their construction > is what is required elsewhere.
The standard seems to be somewhat murky in that regard. I don't see it explicitly spelling out the order for non-bound temporaries, only for bound ones. However, it does give an example listing in 12.2 [class.temporary]/5:
class C { // ... public: C(); C(int); friend C operator+(const C&, const C&); ˜C(); }; C obj1; const C& cr = C(16)+C(23); C obj2;
and then goes on to say:
the expression C(16)+C(23) creates three temporaries. A first temporary T1 to hold the result of the expression C(16), a second temporary T2 to hold the result of the expression C(23), and a third temporary T3 to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference cr. It is unspecified whether T1 or T2 is created first. On an implementation where T1 is created before T2, it is guaranteed that T2 is destroyed before T1.
which seems to imply that the order is guaranteed.