Reputation: 675
I want to understand whether I can safely return an rvalue reference that is passed as an argument to a function and it doesn't get destroyed with the stack unwinding.
struct Struct { int m; };
Struct& f(Struct&& rvalue)
{
std::cout << &rvalue << '\n';
return rvalue;
}
void main()
{
Struct& lvalue1 = f(Struct{ 1 });
std::cout << &lvalue1 << '\n';
Struct& lvalue2 = f(Struct{ 2 });
std::cout << &lvalue2 << '\n';
std::cin.get();
}
Output:
00A3F844
00A3F844
00A3F838
00A3F838
This code produces different addresses for the rvalues. Does that mean that actual constructing of Struct objects happens before a function call and I can safely do this kind of things?
Upvotes: 3
Views: 67
Reputation: 172924
I can safely do this kind of things?
No. Struct{ 1 }
and Struct{ 2 }
construct temporary objects which get destroyed after the full expression. That means the reference lvalue1
and lvalue2
are always dangled. Dereference on them leads to undefined behavior.
All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created
Upvotes: 3