The C++ standard allows to bind const references to rvalues, therefore extending the lifetime of the temporary until the reference goes out of scope. However, I cannot figure out how this is actually compiled, let me explain with an example:
std::string foo() {
return std::string("foo");
}
void bar() {
VeryBigObject obj;
// Perhaps do something with the big object
}
int main(int, char **) {
const std::string &foo_str = foo();
bar();
return 0;
}
As far as I know, using an x86 architecture as an example, what happens there is that first the function foo()
is called and the string object is constructed in the stack, which means that the needed amount of space is subtracted from the rsp
register (assuming 64 bit architecture); afterwards, the rsp
register is returned to its original value, freeing the stack space that the function foo()
was filling, and, if I understand correctly, the call to bar()
would use that stack space to construct the VeryBigObject
, which would overwrite the string.
With all this in mind, how can the lifetime of the string be prolonged after the call to foo()
in the assembly domain?
The temporary return value will be constructed in the stack frame of
main
, either by copying/moving a temporary from that offoo
or, more likely, using RVO to elide the copy and construct it directly in the caller's frame.Once bound to a reference, the temporary will live as long as the reference. Effectively, the temporary is managed in exactly the same way that a named variable with the same scope would be.