returning a (const) reference to a temporary

Discussion in 'C++' started by AdlerSam, Feb 22, 2011.

  1. AdlerSam

    AdlerSam Guest

    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?
     
    AdlerSam, Feb 22, 2011
    #1
    1. Advertising

  2. AdlerSam

    domachine Guest

    On Feb 22, 9:26 am, AdlerSam <> wrote:
    > 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
     
    domachine, Feb 22, 2011
    #2
    1. Advertising

  3. AdlerSam

    domachine Guest

    On Feb 22, 9:55 am, domachine <>
    wrote:
    > On Feb 22, 9:26 am, AdlerSam <> wrote:
    >
    > > 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


    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

    }
     
    domachine, Feb 22, 2011
    #3
  4. AdlerSam wrote:

    > 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.
     
    Paul Brettschneider, Feb 22, 2011
    #4
  5. AdlerSam

    AdlerSam Guest

    On 22 Feb., 10:07, Paul Brettschneider <>
    wrote:
    > AdlerSam wrote:
    > > 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 lifetimeof
    > objects, you usually use smart pointers or containers.
    >
    > Hope that helps.


    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:

    > Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++
    > deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of
    > the temporary to the lifetime of the reference itself, and thus avoids what would otherwise be a common dangling
    > reference error. In the example above, the temporary returned by f() lives until the closing curly brace. (Note this
    > only applies to stack-based references. It doesn’t work for references that are members of objects.)
     
    AdlerSam, Feb 22, 2011
    #5
  6. AdlerSam

    SG Guest

    On 22 Feb., 10:21, AdlerSam wrote:
    > On 22 Feb., 10:07, Paul Brettschneider wrote:
    > > AdlerSam wrote:
    > > > 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.

    >
    > 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:
    >
    > > Normally, a temporary object lasts only until the end of the full
    > > expression in which it appears. However, C++ deliberately specifies that
    > > binding a temporary object to a reference to const on the stack lengthens
    > > the lifetime of the temporary to the lifetime of the reference itself,
    > > and thus avoids what would otherwise be a common dangling reference
    > > error. In the example above, the temporary returned by f() lives until
    > > the closing curly brace. (Note this only applies to stack-based
    > > references. It doesn’t work for references that are members of objects.)


    This is just a simplification of the C++ rules. It only applies to
    cases like

    string source();

    void test() {
    string const& x = source();
    // x still refers to a valid string object
    cout << x << endl;
    }

    However, returning references to function-local objects is never ok,
    NEVER.

    Cheers!
    SG
     
    SG, Feb 22, 2011
    #6
  7. AdlerSam

    Fred Zwarts Guest

    "AdlerSam" <> wrote in message
    news:
    > 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?
     
    Fred Zwarts, Feb 22, 2011
    #7
  8. AdlerSam

    AdlerSam Guest

    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.
     
    AdlerSam, Feb 22, 2011
    #8
  9. AdlerSam Wrote:

    > On 22 Feb., 10:07, Paul Brettschneider
    > <> wrote:
    > > AdlerSam wrote:
    > > > 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.

    >
    > 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:
    >
    > > Normally, a temporary object lasts only until the end of the full

    > expression in which it appears. However, C++
    > > deliberately specifies that binding a temporary object to a

    > reference to const on the stack lengthens the lifetime of
    > > the temporary to the lifetime of the reference itself, and thus

    > avoids what would otherwise be a common dangling
    > > reference error. In the example above, the temporary returned

    > by f() lives until the closing curly brace. (Note this
    > > only applies to stack-based references. It doesn’t work for

    > 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
     
    Bart van Ingen Schenau, Feb 22, 2011
    #9
  10. AdlerSam

    AdlerSam Guest

    > 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!
     
    AdlerSam, Feb 22, 2011
    #10
  11. AdlerSam

    James Kanze Guest

    On Feb 22, 9:21 am, AdlerSam <> wrote:
    > On 22 Feb., 10:07, Paul Brettschneider <>
    > wrote:
    > > AdlerSam wrote:


    > > > 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.


    That would require full garbage collection, and then some, in
    order to implement.

    > > > 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.


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


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


    > To quote the important part:


    > > Normally, a temporary object lasts only until the end of the
    > > full expression in which it appears. However, C++
    > > deliberately specifies that binding a temporary object to
    > > a reference to const on the stack lengthens the lifetime of
    > > the temporary to the lifetime of the reference itself, and
    > > thus avoids what would otherwise be a common dangling
    > > reference error. In the example above, the temporary
    > > returned by f() lives until the closing curly brace. (Note
    > > this only applies to stack-based references. It doesn’t work
    > > for references that are members of objects.)


    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).

    --
    James Kanze
     
    James Kanze, Feb 22, 2011
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexander Stippler
    Replies:
    2
    Views:
    641
    Alexander Stippler
    Jul 4, 2003
  2. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    The temporary vs non-const reference love story

    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=, Nov 4, 2003, in forum: C++
    Replies:
    13
    Views:
    597
    Ron Natalie
    Nov 6, 2003
  3. marco_segurini

    Returning a reference to a temporary

    marco_segurini, Jan 10, 2005, in forum: C++
    Replies:
    1
    Views:
    361
    Dietmar Kuehl
    Jan 10, 2005
  4. Javier
    Replies:
    2
    Views:
    585
    James Kanze
    Sep 4, 2007
  5. George2
    Replies:
    10
    Views:
    613
    Pete Becker
    Dec 17, 2007
Loading...

Share This Page