Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 757
Some programmer dude Avatar asked Jun 07 '18 16:06

Some programmer dude


2 Answers

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.

like image 191
Jarod42 Avatar answered Sep 28 '22 10:09

Jarod42


Lifetime extension only applies to temporaries (and subobjects thereof). my_local_foo is not a temporary.

like image 31
Nicol Bolas Avatar answered Sep 28 '22 10:09

Nicol Bolas