isocppforbids
isocppforbids

Reputation: 389

Returning const reference to temporary

Why does the function foo gives the warning "returning reference to temporary"

const bool& foo()
{
    return true;
}

if declaring bar like this is fine and doesn't generate any kind of warning

const bool& bar = true;

PS: i'm using GCC

Upvotes: 2

Views: 95

Answers (2)

Goswin von Brederlow
Goswin von Brederlow

Reputation: 12322

songyuanyao answered with what the standard says about it. But that doesn't really explain why they decided c++ should behave this way.

It might be easier to think about the code if you think about what the compiler makes of it:

 const bool& bar = true;

The lifetime of the temporary is extended to the lifetime of bar so this code is equivalent to:

const bool temp = true;
const bool& bar = temp;

But lets apply the same to the function return:

const bool& foo()
{
    return true;
}

becomes

const bool& foo()
{
    const boot temp = true
    return temp;
}

Does this make it clearer that you are now returning a reference to an object that gets destroyed? The lifetime of temp can't be extended past the end of the function because 1) the storage location is in the stack frame of fooand that goes away, 2) the caller might have no idea the function returns something with extended lifetime it would have to destroy later, it might only see the function declaration const bool& foo().

So if the compiler could extend the lifetime past the end of the function then it would leak memory.

Upvotes: 1

songyuanyao
songyuanyao

Reputation: 172894

The 2nd one is fine because the lifetime of temporary bool constructed from true will be extended to the lifetime of the reference bar.

Whenever a reference is bound to a temporary object or to a subobject thereof, the lifetime of the temporary object is extended to match the lifetime of the reference

But the lifetime rule doesn't work for the 1st case.

There are following exceptions to this lifetime rule:

  • a temporary bound to a return value of a function in a return statement is not extended: it is destroyed immediately at the end of the return expression. Such return statement always returns a dangling reference.

So foo always returns a dangling reference.

Upvotes: 7

Related Questions