Search code examples
c++c++11standardsobject-lifetime

What am I missing in the C++11 Standard?


I'm not arguing against the result of the code below, for I think it's correct to assume that a const lvalue reference and an rvalue reference, both extend the lifetime of the temporary returned from the function. What surprises me is this paragraph in the Standard, which appears to say the contrary:

12.2p5 (emphasis mine):

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

  • ...
  • ...
  • The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.

Example code:

#include <iostream>

struct A{ A() : i(2) {} int i;};

A f() { A a; return a; }

int main()
{
    A&& a1 = f();
    std::cout << a1.i << '\n';
    const A& a2 = f();
    std::cout << a2.i << '\n';
}

Solution

  • The second context is when a reference is bound to a temporary - except - The lifetime of a temporary bound to the returned value in a function return statement is not extended

    A f() { A a; return a; }
    

    First of all, a isn't a temporary. This may be what you were thinking of:

    A f() { return A(); }
    

    Secondly, the return type of the function is not a reference type. Here is when the rule would apply:

    const A& f() { return A(); }
    

    The temporary from A() is being bound to the return type of const A&. As per the rule, the lifetime of the temporary is not extended.