Const reference to a temporary object - Why?

Discussion in 'C++' started by Dave Rahardja, Oct 29, 2005.

  1. Hi all,

    Although the following definition is legal:

    const int& i = 5;

    ....and that the lifetime of the temporary variable to which i refers is
    identical to i itself, why would anyone want to do this instead of a simple

    const int i = 5;

    ....?

    I can see how binding a const reference to a temporary object is necessary
    (such as when passing an rvalue to a function expecting a const reference),
    but the above usage perplexes me.

    -dr
    Dave Rahardja, Oct 29, 2005
    #1
    1. Advertising

  2. Dave Rahardja wrote:
    > Although the following definition is legal:
    >
    > const int& i = 5;
    >
    > ...and that the lifetime of the temporary variable to which i refers
    > is identical to i itself, why would anyone want to do this instead of
    > a simple
    >
    > const int i = 5;
    >
    > ...?


    You should ask somebody who did/does that.

    > I can see how binding a const reference to a temporary object is
    > necessary (such as when passing an rvalue to a function expecting a
    > const reference), but the above usage perplexes me.


    There is nothing perplexing in that code by itself. It _would_ be
    seriously perplexing in a production codebase. I have never seen
    anything like that in production code.

    V
    Victor Bazarov, Oct 29, 2005
    #2
    1. Advertising

  3. > I have never seen anything like that in production code.
    > V


    Dave -

    Do listen to Victor, I neither had seen this in production not
    Victor's code. And I know Victor for quite some time now (Vitya is it
    25 or 30 years in total is the duration of our acquaintance and
    bestfriendship?).
    Andrej Hristoliubov, Oct 29, 2005
    #3
  4. Dave Rahardja

    Pete C Guest

    > Dave -
    >
    > Do listen to Victor, I neither had seen this in production not
    > Victor's code. And I know Victor for quite some time now (Vitya is it
    > 25 or 30 years in total is the duration of our acquaintance and
    > bestfriendship?).


    That is great advice. If anyone with your level of expertise in c++ has
    experience in IRC, MIME and POP3 protocols I am happy to accept Job
    Application for position in the US. Applicants must have skills of a
    management of a team of the programmers.
    Pete C, Oct 29, 2005
    #4
  5. On Fri, 28 Oct 2005 23:24:40 -0400, "Victor Bazarov" <>
    wrote:

    >Dave Rahardja wrote:
    >> Although the following definition is legal:
    >>
    >> const int& i = 5;
    >>
    >> ...and that the lifetime of the temporary variable to which i refers
    >> is identical to i itself, why would anyone want to do this instead of
    >> a simple
    >>
    >> const int i = 5;
    >>
    >> ...?

    >
    >You should ask somebody who did/does that.


    I did, and his reasons (optimization) turned out to be misguided.

    >> I can see how binding a const reference to a temporary object is
    >> necessary (such as when passing an rvalue to a function expecting a
    >> const reference), but the above usage perplexes me.

    >
    >There is nothing perplexing in that code by itself. It _would_ be
    >seriously perplexing in a production codebase. I have never seen
    >anything like that in production code.


    Neither have I, and I prevented one instance from creeping into our codebase
    (by talking my colleague out of using it for (false) optimization).

    What's perplexing is that such behavior as the lifetime of a temporary bound
    to a const reference is defined at all. Stroustrup even gave an example of it
    in C++PL (Section 5.5, pg 98 in 3rd ed). Seeing that the C++ language doesn't
    seem to support constructs that are not either useful or maintain backward
    compatibility, I'm wondering why such behavior is even defined at all.

    I'm just trying to figure out the motivation behind the behavior, that's all.

    -dr
    Dave Rahardja, Oct 30, 2005
    #5
  6. Dave Rahardja wrote:
    > On Fri, 28 Oct 2005 23:24:40 -0400, "Victor Bazarov" <>
    > wrote:
    >
    > >Dave Rahardja wrote:
    > >> Although the following definition is legal:
    > >>
    > >> const int& i = 5;
    > >>
    > >> ...and that the lifetime of the temporary variable to which i refers
    > >> is identical to i itself, why would anyone want to do this instead of
    > >> a simple
    > >>
    > >> const int i = 5;
    > >>
    > >> ...?

    > >
    > >You should ask somebody who did/does that.

    >
    > I did, and his reasons (optimization) turned out to be misguided.
    >
    > >> I can see how binding a const reference to a temporary object is
    > >> necessary (such as when passing an rvalue to a function expecting a
    > >> const reference), but the above usage perplexes me.

    > >
    > >There is nothing perplexing in that code by itself. It _would_ be
    > >seriously perplexing in a production codebase. I have never seen
    > >anything like that in production code.

    >
    > Neither have I, and I prevented one instance from creeping into our codebase
    > (by talking my colleague out of using it for (false) optimization).
    >
    > What's perplexing is that such behavior as the lifetime of a temporary bound
    > to a const reference is defined at all. Stroustrup even gave an example of it
    > in C++PL (Section 5.5, pg 98 in 3rd ed). Seeing that the C++ language doesn't
    > seem to support constructs that are not either useful or maintain backward
    > compatibility, I'm wondering why such behavior is even defined at all.
    >
    > I'm just trying to figure out the motivation behind the behavior, that's all.


    Consistency.


    Jonathan
    Jonathan Mcdougall, Oct 30, 2005
    #6
  7. Dave Rahardja wrote:
    > On Fri, 28 Oct 2005 23:24:40 -0400, "Victor Bazarov"
    > <> wrote:
    >
    >> Dave Rahardja wrote:
    >>> Although the following definition is legal:
    >>>
    >>> const int& i = 5;
    >>>
    >>> ...and that the lifetime of the temporary variable to which i refers
    >>> is identical to i itself, why would anyone want to do this instead
    >>> of a simple
    >>>
    >>> const int i = 5;
    >>>
    >>> ...?

    >> [..]

    >
    > I'm just trying to figure out the motivation behind the behavior,
    > that's all.


    I don't understand what special motivation except consistency you
    might need. If you think that initialising a const reference by
    binding to a temporary (and thus prolonging the life of the object)
    is OK when passing to a function or as a member of another object,
    then why not stand-alone?

    V
    Victor Bazarov, Oct 30, 2005
    #7
  8. * Victor Bazarov:
    > Dave Rahardja wrote:
    > > On Fri, 28 Oct 2005 23:24:40 -0400, "Victor Bazarov"
    > > <> wrote:
    > >
    > >> Dave Rahardja wrote:
    > >>> Although the following definition is legal:
    > >>>
    > >>> const int& i = 5;
    > >>>
    > >>> ...and that the lifetime of the temporary variable to which i refers
    > >>> is identical to i itself, why would anyone want to do this instead
    > >>> of a simple
    > >>>
    > >>> const int i = 5;
    > >>>
    > >>> ...?
    > >> [..]

    > >
    > > I'm just trying to figure out the motivation behind the behavior,
    > > that's all.

    >
    > I don't understand what special motivation except consistency you
    > might need. If you think that initialising a const reference by
    > binding to a temporary (and thus prolonging the life of the object)
    > is OK when passing to a function or as a member of another object,
    > then why not stand-alone?


    The point is that for a function call, or in an initializer list, and
    especially in a function return, the temporary's life is not prolonged.
    C++ adds _special_ support for local references to const. And then one
    can view binding in function calls / init lists as just a consequence,
    but why allow binding rvalues to local references in the first place?
    The rules would be just as simple if only binding to arguments was
    allowed for rvalues. I think the rules would be _simpler_, and also C++
    compilation, and it would, I think, help to detect some obscure bugs.

    I've tried to think of optimization scenarios, e.g. an 'extern "C"'
    function returning a huge C struct, but no, the feature doesn't seem to
    be able to help the compiler.

    Perhaps the explanation is the same as (this is what's been stated by
    folks Who Should Know) for the non-support of elision of copy
    construction for arguments: some committee member(s) had or knew of
    code, perhaps some company's zillion line application or perhaps a
    popular compiler, that depended on having the language the way it's now
    standardized.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 30, 2005
    #8
  9. On Sun, 30 Oct 2005 02:12:52 GMT, (Alf P. Steinbach) wrote:

    >The point is that for a function call, or in an initializer list, and
    >especially in a function return, the temporary's life is not prolonged.
    >C++ adds _special_ support for local references to const. And then one
    >can view binding in function calls / init lists as just a consequence,
    >but why allow binding rvalues to local references in the first place?
    >The rules would be just as simple if only binding to arguments was
    >allowed for rvalues. I think the rules would be _simpler_, and also C++
    >compilation, and it would, I think, help to detect some obscure bugs.


    Right. The special extension of the temporary's lifetime is what got me
    scratching my head.

    Oh well, it may be one of those things that "just are".

    -dr
    Dave Rahardja, Oct 30, 2005
    #9
  10. Dave Rahardja

    bjarne Guest

    The rules for references are simply the most general and uniform I
    could find. In the cases of arguments and local references, the
    temporary lives as long as the reference to which it is bound. One
    obvious use is as a shorthand for a complicated expression in a
    deeplynested loop. For example:

    for (int i = 0; i<xmax; ++i)
    for (int j = 0; j< ymax; ++j) {
    double& r = a[j];
    for (int k = 0; k < zmax; ++k) {
    // do something with a[j] and a[j][k]
    }
    }

    This can improve readability as well as run-time performance.


    -- Bjarne Stroustrup; http://www.research.att.com/~bs
    bjarne, Oct 30, 2005
    #10
  11. Dave Rahardja

    STOP Guest

    How exactly would the readability and run-time performance be affected
    if we used a regular auto?

    double r = a[j];

    I find the above line more readable - not because it's one char shorter
    than the reference-using one but because it raises no questions and
    head-scratching. And as far as performace goes I thought modern
    compilers could handle the described case just fine. I would really
    like to hear your clarification though!

    Thanks!
    STOP, Oct 30, 2005
    #11
  12. * STOP:
    >
    > double r = a[j];


    You can not assign to the array element via that 'r', so it does not do
    the same job as the reference you think it replaces.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 30, 2005
    #12
  13. * bjarne:
    >
    > The rules for references are simply the most general and uniform I
    > could find.


    I guess it boils down to the subjectively "simple", then. Thanks for
    the explanation.


    >In the cases of arguments and local references, the
    > temporary lives as long as the reference to which it is bound. One
    > obvious use is as a shorthand for a complicated expression in a
    > deeplynested loop. For example:
    >
    > for (int i = 0; i<xmax; ++i)
    > for (int j = 0; j< ymax; ++j) {
    > double& r = a[j];
    > for (int k = 0; k < zmax; ++k) {
    > // do something with a[j] and a[j][k]
    > }
    > }
    >
    > This can improve readability as well as run-time performance.


    Yes, but it does not illustrate a case where binding a local reference
    to const, to an rvalue, is of any direct practical value -- so the
    value of that is presumably only that it provides a simple, general set
    of rules?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 30, 2005
    #13
  14. Dave Rahardja

    bjarne Guest

    A simple, general, set of rules is the ideal. As far as possible, the
    rules for T& and const T& are the same as are the rules for T& and U&.
    However, modify my example a bit

    for (int i = 0; i<xmax; ++i)
    for (int j = 0; j< ymax; ++j) {
    const vector<double>& r = a[j];
    for (int k = 0; k < zmax; ++k) {
    // do something with a[j] and a[j][k]
    }
    }

    You still have the notational advantage, and we wouldn't want to write

    vector<double> r = a[j];

    and copy 1000 elements. Obviously, it is also more realistic to have
    a[j] a vector than a double (since I proceeded to subscript it :)

    -- Bjarne Stroustrup; http://www.research.att.com/~bs
    bjarne, Oct 31, 2005
    #14
  15. Dave Rahardja

    STOP Guest

    >You can not assign to the array element via that 'r', so it does not do
    >the same job as the reference you think it replaces.


    Oh, but.. yes, of course - how very silly of me!
    I hope *nobody* saw this utterly shameful slip-up :))
    ...exqueezemoi eurobody
    STOP, Oct 31, 2005
    #15
  16. * bjarne:
    > A simple, general, set of rules is the ideal. As far as possible, the
    > rules for T& and const T& are the same as are the rules for T& and U&.
    > However, modify my example a bit
    >
    > for (int i = 0; i<xmax; ++i)
    > for (int j = 0; j< ymax; ++j) {
    > const vector<double>& r = a[j];
    > for (int k = 0; k < zmax; ++k) {
    > // do something with a[j] and a[j][k]
    > }
    > }
    >
    > You still have the notational advantage, and we wouldn't want to write
    >
    > vector<double> r = a[j];
    >
    > and copy 1000 elements. Obviously, it is also more realistic to have
    > a[j] a vector than a double (since I proceeded to subscript it :)


    Heh... ;-) I didn't even notice that type-o, I guess because that
    wasn't what you tried to communicate.

    However, the above isn't an example of the temporary lifetime extension,
    either.

    Somewhere there must be an example of practical usefulness, I'm sure!

    On the third hand, I just stumbled over an issue seemingly a consequence
    of this general idea of _generating_ a tempory to bind a reference to,
    namely that with the current standard the following should not compile,
    and indeed does not compile with g++ 3.4.4, nor with Comeau Online
    4.3.3, because of that generated temporary requiring copy construction:

    #include <memory>

    struct E {};

    typedef std::auto_ptr<E> EPtr;

    EPtr foo() { return EPtr( new E ); }
    EPtr bar( EPtr const& ) { return EPtr( new E ); }

    int main()
    {
    bar( foo() ); // Oops! Not allowed by current rules!
    }

    After a bit of searching I found that this utter silliness, which also
    was a stumbling block for Andrei's Mojo, has been adressed by core issue
    391, <url:
    http://www2.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391>, and
    "voted into WP" (that's C++0x, isn't it?), and that's nice.

    But that doesn't help us until C++0x, which is -- when?


    Cheers,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 3, 2005
    #16
    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. John Ky
    Replies:
    9
    Views:
    436
    John Ky
    Feb 23, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,840
    Smokey Grindel
    Dec 2, 2006
  3. Javier
    Replies:
    2
    Views:
    561
    James Kanze
    Sep 4, 2007
  4. Replies:
    10
    Views:
    1,349
    James Kanze
    Nov 27, 2008
  5. zade
    Replies:
    5
    Views:
    404
Loading...

Share This Page