Hiding const references bound to temporary

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • casul

    #1

    Hiding const references bound to temporary

    Hi All,

    Given the following code :

    char const & identity( char const &c ) { return c; }

    char const & f( ) { return identity('A'); }
    char const & g( ) { return 'A'; }

    Of course, the compiler complains of function 'g' returning a
    reference to a temporary. But the compiler (I used gcc 4.2.x) doesn't
    say anything regarding the function 'f'. I know that temporaries bound
    to constant references have a life span that extends to the expression
    in which the function call where the bounding took place is evaluated.
    Now given that, is the fact of returning in turn the constant
    reference returned by 'identity' considered to be part of the
    expression in which 'identity' is evaluated, ie the expression is

    return identity('A');

    or does the evaluated expression just consist of the function call
    'identity', ie:

    identity('A');

    ?

    I would have said the first case. But I'm not sure. I guess the main
    question is: does a call to 'f' yield undefined behaviour ?

    Thanks for your comments,

    Olivier.
  • Victor Bazarov

    #2
    Re: Hiding const references bound to temporary

    casul wrote:
    Given the following code :
    >
    char const & identity( char const &c ) { return c; }
    >
    char const & f( ) { return identity('A'); }
    char const & g( ) { return 'A'; }
    >
    Of course, the compiler complains of function 'g' returning a
    reference to a temporary. But the compiler (I used gcc 4.2.x) doesn't
    say anything regarding the function 'f'. I know that temporaries bound
    to constant references have a life span that extends to the expression
    in which the function call where the bounding took place is evaluated.
    Now given that, is the fact of returning in turn the constant
    reference returned by 'identity' considered to be part of the
    expression in which 'identity' is evaluated, ie the expression is
    >
    return identity('A');
    No, it's not an expression. It's a *control statement*. As part of the
    statement the expression 'identity('A')' is evaluated (and it's a full
    expression).
    or does the evaluated expression just consist of the function call
    'identity', ie:
    >
    identity('A');
    >
    ?
    There is no semicolon in an expression. A semicolon is a *statement*
    separator. Drop the semicolon and you got yourself an expression.
    I would have said the first case. But I'm not sure. I guess the main
    question is: does a call to 'f' yield undefined behaviour ?
    IMHO, yes. The temporary disappears as soon as the full expression is
    evaluated. By the time anybody attempts to use the return value of the
    'identity' function call with 'A' as the argument in any way, the
    reference returned has become invalid. Any use of it (like passing up
    to the caller of 'f') would be undefined behaviour.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • James Kanze

      #3
      Re: Hiding const references bound to temporary

      On Oct 14, 8:35 pm, casul <olivier.gr...@ gmail.comwrote:
      Given the following code :
         char const & identity( char const &c ) { return c; }
         char const & f( ) { return identity('A'); }
         char const & g( ) { return 'A'; }
      Of course, the compiler complains of function 'g' returning a
      reference to a temporary. But the compiler (I used gcc 4.2.x)
      doesn't say anything regarding the function 'f'.
      How could it? Suppose that identity() and f() where in
      different translation units. How could the compiler know that f
      is in fact returning a reference to it's temporary?
      I know that temporaries bound to constant references have a
      life span that extends to the expression in which the function
      call where the bounding took place is evaluated.
      Then you know something that is completely wrong. A temporary
      has a lifetime until the end of the full expression in which it
      appears. *IF* the temporary is used to initialize a reference,
      it's lifetime is extended to match that of the reference (except
      that a temporary bound to a reference being returned explicitly
      doesn't have its lifetime extended). But whether the temporary
      is bound to some other reference or not has no effect on its
      lifetime.
      Now given that, is the fact of returning in turn the constant
      reference returned by 'identity' considered to be part of the
      expression in which 'identity' is evaluated, ie the expression
      is
          return identity('A');
      or does the evaluated expression just consist of the function
      call 'identity', ie:
          identity('A');
      ?
      The temporary 'A' is used to initialize the reference which is
      an argument of identity. The lifetime of that reference ends on
      return from identity, which is *before* the end of the full
      expression. So the lifetime of the temporary is at the end of
      the full expression. (Actually, there's a slight extension
      here; if the temporary were used to directly initialize the
      return value, it's lifetime would be extended until the return
      value was constructed. That's not the case here, however.)
      I would have said the first case. But I'm not sure. I guess
      the main question is: does a call to 'f' yield undefined
      behaviour ?
      Of course.

      --
      James Kanze (GABI Software) email:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      Working...