The temporary vs non-const reference love story

Discussion in 'C++' started by =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=, Nov 4, 2003.

  1. Hello.

    Binding a temporary to a non-const reference is illegal. Everybody
    should be tired of hearing that. So should I. But then I found myself
    wondering about a small piece of code I was writing:

    void cipher(unsigned long& xa, unsigned long& xb)
    {
    // ...
    xa = // ...
    xb = // ...
    }

    int main()
    {
    unsigned long a = 1111111;
    unsigned long b = 2222222;
    cipher(a, b);
    }

    The function cipher() is supposed to transform the two /long/ arguments
    received. It might have had its arguments in the form of pointers, but
    the author chose to allow users to use a simple, uncluttered cipher(a,
    b) call. It might also have been made to return an object containing the
    two ciphered values instead.

    Which of the two alternatives aforementioned do you think is better? Is
    there any other one I have overlooked?

    Thank you,

    --
    Ney André de Mello Zunino
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=, Nov 4, 2003
    #1
    1. Advertising

  2. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    wogston Guest

    > void cipher(unsigned long& xa, unsigned long& xb)
    > {
    > // ...
    > xa = // ...
    > xb = // ...
    > }
    >
    > int main()
    > {
    > unsigned long a = 1111111;
    > unsigned long b = 2222222;
    > cipher(a, b);
    > }


    That is not illegal. This is:

    int& foo()
    {
    int a = 7;
    return a;
    }


    "int a" lives in stack. When you return from this function, the memory is
    freed, so the reference is referring to memory that is not anymore in scope.
    wogston, Nov 4, 2003
    #2
    1. Advertising

  3. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Larry Smith Guest

    > That is not illegal. This is:
    >
    > int& foo()
    > {
    > int a = 7;
    > return a;
    > }
    >
    >
    > "int a" lives in stack. When you return from this function, the memory is
    > freed, so the reference is referring to memory that is not anymore in

    scope.

    That's not the issue he was talking about. This is:

    void foo(MyClass &Var)
    {
    // Whatever
    }

    foo(MyClass());

    That's illegal because you can't pass a temporary to a non-const reference
    parameter, only a *const* reference parameter. IOW, you need to make the
    above parameter "const MyClass &". Actually, I don't understand what his
    issue is. There's nothing wrong with the code he posted (he's not passing
    temporaries).
    Larry Smith, Nov 4, 2003
    #3
  4. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Oplec Guest

    wogston wrote:
    >>void cipher(unsigned long& xa, unsigned long& xb)
    >>{
    >> // ...
    >> xa = // ...
    >> xb = // ...
    >>}
    >>
    >>int main()
    >>{
    >> unsigned long a = 1111111;
    >> unsigned long b = 2222222;
    >> cipher(a, b);
    >>}

    >
    >
    > That is not illegal. This is:
    >
    > int& foo()
    > {
    > int a = 7;
    > return a;
    > }
    >
    >
    > "int a" lives in stack. When you return from this function, the memory is
    > freed, so the reference is referring to memory that is not anymore in scope.
    >
    >


    It is not illegal to return a reference to a local variable, but it is
    wrong.
    Oplec, Nov 4, 2003
    #4
  5. Ney André de Mello Zunion wrote:
    >


    [snip]

    > Which of the two alternatives aforementioned do you think is better?


    Define 'better'

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Nov 4, 2003
    #5
  6. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    wogston Guest

    > It is not illegal to return a reference to a local variable, but it is
    > wrong.


    What does 'wrong' mean in context of C++ programming? Since it appears you
    want to imply that it is correct, as far as syntax of the language is
    concerned, then there is only one question left:

    Undefined, or defined behaviour? If defined, then how is it wrong? If it is
    undefined, how it is not illegal?

    So which wrong you mean? :)
    wogston, Nov 4, 2003
    #6
  7. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Ron Natalie Guest

    "wogston" <> wrote in message news:bo8ovb$cki$...
    > > It is not illegal to return a reference to a local variable, but it is
    > > wrong.

    >
    > What does 'wrong' mean in context of C++ programming? Since it appears you
    > want to imply that it is correct, as far as syntax of the language is
    > concerned, then there is only one question left:
    >
    > Undefined, or defined behaviour? If defined, then how is it wrong? If it is
    > undefined, how it is not illegal?


    Undefined behavior, but it is not ill-formed. That is, the compiler is not obligated
    to detect and issue a diagnostic if you return a reference to an object that is about
    to go out of scope, but it is undefined behavior (that is, very bad) to do so.
    Ron Natalie, Nov 4, 2003
    #7
  8. Larry Smith wrote:

    [...]

    > Actually, I don't understand what his issue is. There's nothing wrong
    > with the code he posted (he's not passing temporaries).


    Thank you all for your responses. After reading the above comment, I
    decided to try the code with other compilers --something which I should
    have done before posting in the first place-- only to see no warning
    about temporaries being used on that call.

    The other compiler in question is GCC 3.3.1 and its diagnostic led me to
    the source of the problem. Contrary to the code shown in my initial
    message, the actual one had a type mismatch between the variables
    declared and the arguments expected by the function. The variables were
    declared as /long/ while the function expected non-const references to
    /unsigned long/.

    Here is what GCC had to say about it:

    teste.cpp:14: error: could not convert `a' to `long unsigned int&'
    blowfish.h:7: error: in passing argument 1 of `void Blowfish::cifra(long
    unsigned int&, long unsigned int&)'

    And here is the misleading warning produced by BCC:

    Warning W8030 teste.cpp 14: Temporary used for parameter 'xa' in call to
    'cifra(unsigned long &,unsigned long &)' in function main(int,char * *)

    Fixing the variables declarations to make them match the type of the
    references expected by the function made both compilers accept the code.

    Regards,

    --
    Ney André de Mello Zunino
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=, Nov 5, 2003
    #8
  9. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Cy Edmunds Guest

    "Ney André de Mello Zunion" <> wrote in message
    news:bo7an1$18vqa7$-berlin.de...
    > Hello.
    >
    > Binding a temporary to a non-const reference is illegal. Everybody
    > should be tired of hearing that. So should I. But then I found myself
    > wondering about a small piece of code I was writing:
    >
    > void cipher(unsigned long& xa, unsigned long& xb)
    > {
    > // ...
    > xa = // ...
    > xb = // ...
    > }
    >
    > int main()
    > {
    > unsigned long a = 1111111;
    > unsigned long b = 2222222;
    > cipher(a, b);
    > }
    >
    > The function cipher() is supposed to transform the two /long/ arguments
    > received. It might have had its arguments in the form of pointers, but
    > the author chose to allow users to use a simple, uncluttered cipher(a,
    > b) call. It might also have been made to return an object containing the
    > two ciphered values instead.
    >
    > Which of the two alternatives aforementioned do you think is better? Is
    > there any other one I have overlooked?
    >
    > Thank you,
    >
    > --
    > Ney André de Mello Zunino


    I think the signature

    SomeClass cipher(unsigned long, unsigned long);

    is clearer. Your version is ambiguous because it is not clear if xa and xb
    need to be initialized before the call.

    --
    Cy
    http://home.rochester.rr.com/cyhome/
    Cy Edmunds, Nov 5, 2003
    #9
  10. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    wogston Guest

    > Undefined behavior, but it is not ill-formed. That is, the compiler is
    not obligated
    > to detect and issue a diagnostic if you return a reference to an object

    that is about
    > to go out of scope, but it is undefined behavior (that is, very bad) to do

    so.

    It was a rhetoric question, but thanks anyway. ;-)
    wogston, Nov 5, 2003
    #10
  11. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Ron Natalie Guest


    >
    > Actually, I don't understand what his issue is. There's nothing wrong
    > with the code he posted (he's not passing temporaries).
    >

    Yes, he is. Since the types don't match, but are convertable, a temporary
    converted value is generated.
    Ron Natalie, Nov 5, 2003
    #11
  12. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Larry Smith Guest

    > > Actually, I don't understand what his issue is. There's nothing wrong
    > > with the code he posted (he's not passing temporaries).
    > >

    > Yes, he is. Since the types don't match, but are convertable, a temporary
    > converted value is generated.


    There's no type mismatch in his original post.
    Larry Smith, Nov 5, 2003
    #12
  13. Ron Natalie wrote:

    > Yes, he is. Since the types don't match, but are convertable, a temporary
    > converted value is generated.


    There seems to be something wrong anyway: BCC managed to make the type
    conversion from long to unsigned long, but then complained about
    temporaries being passed, while saying nothing about the automatic
    conversion itself. GCC, on the other hand, refused to do the type
    conversion and failed to compile.

    I am not sure about what the proper behavior should be, but I would hope
    that, in a situation like that, the compilers would *warn* both about
    the type conversion (since there is a good chance of it being unwanted)
    and the creation of temporaries. That way, a user could have a better
    idea of where he went wrong.

    Regards,

    --
    Ney André de Mello Zunino
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=, Nov 6, 2003
    #13
  14. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    Ron Natalie Guest

    "Ney André de Mello Zunino" <> wrote in message news:boc76s$1coms3$-berlin.de...

    > There seems to be something wrong anyway: BCC managed to make the type
    > conversion from long to unsigned long, but then complained about
    > temporaries being passed, while saying nothing about the automatic
    > conversion itself. GCC, on the other hand, refused to do the type
    > conversion and failed to compile.
    >

    Either way is fine. The standard doesn't say anything about the message
    issued for ill-formed programs, just that one should be issued. Actually
    both errors are fine. It's not clear to the compiler (or even me) which is
    the real error here. It could either be that you didn't intend a conversion
    here (mismatched args) or you are trying to bind the converted temporary
    to an non-const reference.
    Ron Natalie, Nov 6, 2003
    #14
    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. qazmlp
    Replies:
    4
    Views:
    1,389
    Buster
    May 6, 2004
  3. Thomas W

    NSLU2 and python - a love story ?

    Thomas W, Jun 1, 2005, in forum: Python
    Replies:
    3
    Views:
    651
    Terry Reedy
    Jun 2, 2005
  4. George2
    Replies:
    10
    Views:
    595
    Pete Becker
    Dec 17, 2007
  5. Love love love

    , Jun 3, 2009, in forum: C++
    Replies:
    0
    Views:
    414
Loading...

Share This Page