C++: Life span of temporary arguments?

C++Destructor

C++ Problem Overview


When creating a new instance of a MyClass as an argument to a function like so:

class MyClass
{
  MyClass(int a);
};    

myFunction(MyClass(42));

Does the standard make any guarantees on the timing of the destructor?

Specifically, can I assume that it is going to be called before the next statement after the call to myFunction() ?

C++ Solutions


Solution 1 - C++

Temporary objects are destroyed at the end of the full expression they're part of.

A full expression is an expression that isn't a sub-expression of some other expression. Usually this means it ends at the ; (or ) for if, while, switch etc.) denoting the end of the statement. In your example, it's the end of the function call.

Note that you can extend the lifetime of temporaries by binding them to a const reference. Doing so extends their lifetime to the reference's lifetime:

MyClass getMyClass();

{
  const MyClass& r = getMyClass(); // full expression ends here
  ...
} // object returned by getMyClass() is destroyed here

If you don't plan to change the returned object, then this is a nice trick to save a copy constructor call (compared to MyClass obj = getMyClass();), in case return value optimization was not being applied. Unfortunately it isn't very well known. (I suppose C++11's move semantics will render it less useful, though.)

Solution 2 - C++

Everyone has rightly cited 12.2/3 or similar, which answers your question:

> Temporary objects are destroyed as the > last step in evaluating the > full-expression that (lexically) > contains the point where they were > created.

I find it amusing that over the next page in my printing of the standard, 12.2/4 says:

> There are two contexts in which > temporaries are destroyed at a > different point than the end of the > full-expression.

Neither of them applies to your example, they both relate to the use of temporaries in initializers. But it does go to show that you have to keep your wits about you when dealing with a tricky beast like the C++ standard.

Solution 3 - C++

The standard does indeed offer guarantees - from section 12.2/5:

> A temporary bound to a reference > parameter in a function call (5.2.2) > persists until the completion of the > full expression containing the call

However, in your code it is not clear if the parameter is being passed by reference or by value, though at some point a copy constructor which does take a reference will be used.

Solution 4 - C++

In section 12.2, Temporary Objects, clause 3, the ANSI/ISO C standard states: "... Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created."

This is closely related to the concept of Sequence Points. When a sequence point is reached, all side-effects of expressions are guaranteed to have taken place.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionshooshView Question on Stackoverflow
Solution 1 - C++sbiView Answer on Stackoverflow
Solution 2 - C++Steve JessopView Answer on Stackoverflow
Solution 3 - C++anonView Answer on Stackoverflow
Solution 4 - C++Mike MuellerView Answer on Stackoverflow