Search code examples
c++referencereturnlanguage-lawyerlifetime

Is returning a reference to a local object undefined behavior in copy initialization?


Consider the following code:

struct foo
{
    foo(foo const&) = default;  // To make sure it exists
};

foo& get_local_foo_reference()
{
    foo my_local_foo;
    return my_local_foo;  // Return a reference to a local variable
}

int main()
{
    foo my_foo = get_local_foo_reference();
}

Now everybody would agree that returning a reference to a local variable is bad and lead to undefined behavior.

But in the case of copy initialization (as shown in the code above) the argument is a constant lvalue reference, so it should be a reference initialization of the argument, which extends the life-time of the reference.

Is this valid, or is it still undefined behavior?


Solution

  • Lifetime extension only applies to temporaries when bounds to const reference or r-value reference. (temporary cannot be bound to non const l-value reference)

    Even if you return temporary, it would be UB:

    const foo& create_foo() { return foo{}; } // Also UB
    

    From http://eel.is/c++draft/class.temporary#6.10:

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