returning a (const) reference to a temporary

A

AdlerSam

Hi,

I wonder why the following two lines produce a warning:

class X {};
const X &f() {return X();}

$ g++ -c ref.cpp
ref.cpp: In function ‘const X& f()’:
ref.cpp:2: warning: returning reference to temporary

As far as I understand, a const reference _extends_ the lifetime of a
temporary until the very last reference instance that refers to the
temporary goes out of scope. Thus, where is the problem that justyfies
the warning?
 
D

domachine

Hi,

I wonder why the following two lines produce a warning:

class X {};
const X &f() {return X();}

$ g++ -c ref.cpp
ref.cpp: In function ‘const X& f()’:
ref.cpp:2: warning: returning reference to temporary

As far as I understand, a const reference _extends_ the lifetime of a
temporary until the very last reference instance that refers to the
temporary goes out of scope. Thus, where is the problem that justyfies
the warning?

Who told you, the thing with the lifetime? I think you misunderstood
something. The const does to a reference, is making it constant.
Comparable to constant pointers.

class Test
{
public:
void non_const_method()
{
// Do something like writing to a member-variable
// ...
}

void const_method() const
{
// Do something constant like reading a variable
// ...
}
}

int main()
{
const Test& ref = Test();

ref.non_const_method(); // This doesn't work
ref.const_method(); // Yes this does
}


This is the only thing the const keyword does. We don't have a garbage
collector in C++.

Best regards Dominik
 
D

domachine

Who told you, the thing with the lifetime? I think you misunderstood
something. The const does to a reference, is making it constant.
Comparable to constant pointers.

class Test
{
public:
    void non_const_method()
    {
        // Do something like writing to a member-variable
        // ...
    }

    void const_method() const
    {
        // Do something constant like reading a variable
        // ...
    }

}

int main()
{
    const Test& ref = Test();

    ref.non_const_method();  // This doesn't work
    ref.const_method();  // Yes this does

}

This is the only thing the const keyword does. We don't have a garbage
collector in C++.

Best regards Dominik

Sorry there's a mistake in my main.

It should be:

int main()
{
Test test;
const Test& ref = test;

ref.non_const_method(); // This doesn't work
ref.const_method(); // Yes this does

}
 
P

Paul Brettschneider

AdlerSam said:
Hi,

I wonder why the following two lines produce a warning:

class X {};
const X &f() {return X();}

$ g++ -c ref.cpp
ref.cpp: In function ‘const X& f()’:
ref.cpp:2: warning: returning reference to temporary

As far as I understand, a const reference _extends_ the lifetime of a
temporary until the very last reference instance that refers to the
temporary goes out of scope. Thus, where is the problem that justyfies
the warning?

This assumption is - of course - nonsense. If you want to manage lifetime of
objects, you usually use smart pointers or containers.

Hope that helps.
 
S

SG

F

Fred Zwarts

AdlerSam said:
Hi,

I wonder why the following two lines produce a warning:

class X {};
const X &f() {return X();}

$ g++ -c ref.cpp
ref.cpp: In function ‘const X& f()’:
ref.cpp:2: warning: returning reference to temporary

As far as I understand, a const reference _extends_ the lifetime of a
temporary until the very last reference instance that refers to the
temporary goes out of scope. Thus, where is the problem that justyfies
the warning?

Where does the reference (the return value in this case) go out of scope?
 
A

AdlerSam

Ok, got it, thanks for your help. I just got confused by the quoted
article, making me think that references may behave "smarter" than
plain pointers in that they may prevent the destruction of local
variables until they themselves go out of scope.
 
B

Bart van Ingen Schenau

AdlerSam said:
Hm - Then where do I have mistaken Herb Sutters GotW #88:?

http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-
const/

To quote the important part:

expression in which it appears. However, C++
reference to const on the stack lengthens the lifetime of
avoids what would otherwise be a common dangling
by f() lives until the closing curly brace. (Note this
references that are members of objects.)

You go wrong when you assume this lifetime extension is transitive.
The lifetime of a temporary is indeed extended, but only to the lifetime of
the *initial* reference it is bound to.
If you use that reference to initialise a second reference, then the
lifetime of the temporary is not further extended.

In your initial example, the temporary is bound to the reference being
returned, so the lifetime of the temporary is extended to the lifetime of
the return value.
As this creates a great risk of getting a dangling reference (for example,
when you have the code "const X& x = f();"), most compilers will warn you
when you try to return a reference to something that won't live long enough
to be useful in the caller.

Bart v Ingen Schenau
 
A

AdlerSam

You go wrong when you assume this lifetime extension is transitive.

Thanks particularly for this one sentence: It just explains everything
and puts my "gut feeling" on when references extend the lifetime of a
temporary and when it doesn't back on solid grounds!
 
J

James Kanze

That would require full garbage collection, and then some, in
order to implement.
Hm - Then where do I have mistaken Herb Sutters GotW #88:?

To quote the important part:

You seem to misunderstand two important points:

-- first, the lifetime of the temporary is extended only to the
end of the lifetime of the reference the temporary
initializes, not to any other references, and

-- second, return involves a copy, so the reference being
returned is not the reference the temporary initialized.

Herb has simply used a common, but misleading formulation of the
rule, which is better stated as "initializing a reference with
a temporary extends the lifetime of the temporary to that of the
reference". When returning a reference, you (formally, at
least) initialize a local temporary reference with the return
expression, then return a copy of that reference, with the local
temporary reference going out of scope (and thus triggering the
destruction of the temporary used to initialize it).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top