C++ Destruction of Temporary Object in an Expression

C++ destruction of temporary object in an expression

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. [12.2/3]

Temporary object destruction

With your compiler and options the temporary is elided (optimized away), which is permitted.

Thus there is no temporary.

Thus there is no missing constructor and destructor call pair.


It's also well worth noting that the copy and move constructors are the only constructors where the compiler is allowed to assume that the constructor has no side effects, even when it knows better.

C++11 §12.8/31:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. […]

When exactly does the destruction of a temporary object happen in a function call?

Actually, both of these cases are okay.

In the first case, binding the temporary to a const reference extends its lifetime to that of s. So it won't be destroyed until main exits.

In the second case, the temporary is destroyed after the end of the full-expression containing it. In this case, it is the function call. If you stored that C string anywhere which outlived bar and then tried to access it, then you're due a date with undefined behaviour.

Does standard C++11 guarantee that temporary object passed to a function will have been destroyed after the end of the function?

Well, you already quoted all the text that tells us the temporary's lifetime ends at the end of the full-expression. So, yes, "T destroyed" will always come last.

If the destruction had no observable side-effects then, per the as-if rule, it could actually happen at any time afterwards… but that's moot because, well, it wouldn't be observable.

However, the final two snippets you presented are not generally equivalent, because you fixed the order of construction/initialisation in a way that it wasn't before. Function arguments have an unspecified evaluation order. Again, though, for this particular T the difference is not observable.

Exceptions to the order of destruction for temporary objects?

I assume they're referring to any temporaries bound to references. The lifetime of the temporary is extended to the lifetime of the reference, while other temporaries may still be destroyed.

When is the destructor of the temporary called

I wanted to know when the destructor of a temporay is called for both
C++03 and C++11

The destructor of an R-Value (temporary) is called at the end of the expression.

Give your code:

foo method()
{
foo f;
......
......
return foo;
}

void doSomething()
{
foo f = method();
....
}

method() creates an object. When that object goes out of scope (at the end of method), the destructor is called (in the event of no optimisations).

The call "foo f="... causes the copy constructor for foo to be called. After that the expression ends, causing the returned object (temporary) to be destructed. The object "f"'s destructor is called when it goes out of scope at the end of doSomething.

Temporary object destruction

With your compiler and options the temporary is elided (optimized away), which is permitted.

Thus there is no temporary.

Thus there is no missing constructor and destructor call pair.


It's also well worth noting that the copy and move constructors are the only constructors where the compiler is allowed to assume that the constructor has no side effects, even when it knows better.

C++11 §12.8/31:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. […]

Why does the second destruction of the temporary object on the code below occurs before the message End of f is printed?

First of all, even if you copied this from the standard, it's still undefined behavior, so the answer could be just the compiler felt like it.

However, I understand your question is why End of f is printed after the second ~C() and not at the end of the scope (i.e. after the print).

The answer is that temporaries in an expression are destroyed when it ends. Since C() creates a temporary, it will be destroyed at the ;.

How to comprehend Temporary objs are destroyed as the last step in evaluating the full-expression?Could anyone make it clear by some simple example?

Simple example. This expression produces a temporary object:

std::string("test")

Here, that expression is used as a subexpression:

function(std::string("test"));
// point A

At point A, the temporary object has been destroyed because the point is after the full-expression where the temporary object was created.


Here is an example of how to write a bug if this rule is not understood:

const std::string& function(const std::string& arg) {
return arg;
}

const std::string& ref = function("test");
std::cout << ref;

Here, the temporary object that was created as the argument is destroyed after the full expression, and therefore ref has become invalid - a dangling reference. The behaviour is undefined when the invalid reference is inserted into the output stream.



Related Topics



Leave a reply



Submit