Returning temporary object and binding to const reference
This is a C++ feature. The code is valid and does exactly what it appears to do.
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, and thus avoids what would otherwise be a common dangling-reference error. In the example above, the temporary returned by foo()
lives until the closing curly brace.
P.S: This only applies to stack-based references. It doesn’t work for references that are members of objects.
Full text: GotW #88: A Candidate For the “Most Important const” by Herb Sutter.
gruszczy
I lead and manage the Google Assistant on Speakers team.
Updated on July 05, 2022Comments
-
gruszczy almost 2 years
Possible Duplicate:
Does a const reference prolong the life of a temporary?My compiler doesn't complain about assigning temporary to const reference:
string foo() { return string("123"); }; int main() { const string& val = foo(); printf("%s\n", val.c_str()); return 0; }
Why? I thought that string returned from
foo
is temporary and val can point to object which lifetime has finished. Does C++ standard allow this and prolongs the lifetime of returned object? -
xryl669 over 10 yearsAlso, please notice that through no copy is done on the string here, a copy constructor for string must exists and be accessible.
-
underscore_d about 8 yearsre the P.S, this is very important, and the dupe SO thread linked above has good illustrations of this
-
dashesy almost 8 years@xryl669 Does c++17 Guaranteed copy elision mean copy constructor is no longer necessary? quote: ``` when the source object is a temporary ```
-
underscore_d almost 8 years@dashesy What do you mean? A copy constructor was never "necessary" in such cases. In practice, if the
return
expression off()
returned an unnamed rvalue, RVO would almost certainly have kicked in and elided the copy construction, instead directly constructing the returned object in the caller's receiving location (variable). Had thereturn
expression returned a named object, NRVO might've done the same. What C++17's guaranteed copy elision achieves is to require elision in the former, simpler case of RVO. -
dashesy almost 8 years@underscore_d yes, no copy is made but xryl669 comment states that still a copy constructor was needed.
-
underscore_d almost 8 years@dashesy Oops, I get it now. Fair question. And thankfully the answer is trivial to find: stackoverflow.com/a/38043447/2757035 That's a yes. It follows logically from the guaranteed part of the name. If copy elision is guaranteed, then there doesn't need to be an accessible copy or move constructor, for it is guaranteed not to ever be needed.