Returning temporary object and binding to const reference

23,220

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.

Share:
23,220
gruszczy
Author by

gruszczy

I lead and manage the Google Assistant on Speakers team.

Updated on July 05, 2022

Comments

  • gruszczy
    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
    xryl669 over 10 years
    Also, please notice that through no copy is done on the string here, a copy constructor for string must exists and be accessible.
  • underscore_d
    underscore_d about 8 years
    re the P.S, this is very important, and the dupe SO thread linked above has good illustrations of this
  • dashesy
    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
    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 of f() 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 the return 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
    dashesy almost 8 years
    @underscore_d yes, no copy is made but xryl669 comment states that still a copy constructor was needed.
  • underscore_d
    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.