Topic: Quirk/loophole with return by reference


Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/07/15
Raw View
On 28 Jun 1999 23:41:43 GMT, James Shaw <jhs@entropy.cs.princeton.edu> wrote:

>inline const X & foo()
>{
> X x(0, 0, 0);
> // Do some stuff to x....
> return x;   // This generates a compiler warning.
>}

Compiler warning is good and useful.


>inline const X & bar()
>{
> return X(1, 2, 3); // But this doesn't!
>}

Compiler should generate a warning here too.

Note that the following is well formed
   X foo();
   int main() { const X& x=foo(); x.action(); } // 'x' destroyed now


>I'm mostly curious if this is compiler-specific (I'm using
>Metrowerks C++, btw), or if it is part of the standard.

Report the quality of implementation problem to Metrowerks.



>Please post any replies here or email me.

What other choices do we have?!

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jhs@entropy.cs.princeton.edu (James Shaw)
Date: 1999/06/28
Raw View
Hello everyone,

I have a question regarding the C++ standard that came
up while I was writing a new class today.

I had the following two inline functions:

inline const X & foo()
{
 X x(0, 0, 0);
 // Do some stuff to x....
 return x;   // This generates a compiler warning.
}

inline const X & bar()
{
 return X(1, 2, 3); // But this doesn't!
}

I understand why I shouldn't return a local stack variable x
as a reference (it isn't around any more!), and I corrected
the code for foo() which was just sloppiness on my part.

What I don't understand is why the code in bar() is allowed.
Any explanations to why a reference to the temporary returned
is allowed would be appreciated.  Any explanations to how
the compiler writer might work this would also be interesting.

I'm mostly curious if this is compiler-specific (I'm using
Metrowerks C++, btw), or if it is part of the standard.
I like to keep my coding style portable and will probably
switch bar()'s return type to X if this quirk isn't standard.

Please post any replies here or email me.

Thanks,
James



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "SteveL" <steve.love@tnt.co.uk>
Date: 1999/06/29
Raw View

>inline const X & bar()
>{
> return X(1, 2, 3); // But this doesn't!
>}
>
>I understand why I shouldn't return a local stack variable x
>as a reference (it isn't around any more!), and I corrected
>the code for foo() which was just sloppiness on my part.

exactly right


>What I don't understand is why the code in bar() is allowed.
>Any explanations to why a reference to the temporary returned
>is allowed would be appreciated.  Any explanations to how
>the compiler writer might work this would also be interesting.

the second version (as I understand the workings of such things) creates a
temporary object of type X which gets returned to the caller. Thus, some
code like

X z;
    z = bar ();

will work fine because z is assigned the value of the temporary object (via
the reference). After this assignment takes place, the temporary object is
destroyed (making the reference invalid) but leaving the data in z.

See?


>I'm mostly curious if this is compiler-specific (I'm using
>Metrowerks C++, btw), or if it is part of the standard.
>I like to keep my coding style portable and will probably
>switch bar()'s return type to X if this quirk isn't standard.

It's standard as far as I can tell.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: wmm@fastdial.net
Date: 1999/06/29
Raw View
In article <7l8h7p$su1$1@cnn.Princeton.EDU>,
  jhs@entropy.cs.princeton.edu (James Shaw) wrote:
> inline const X & bar()
> {
>  return X(1, 2, 3); // But this doesn't!
> }
>
> What I don't understand is why the code in bar() is allowed.

It isn't.  According to 12.2p5, "A temporary bound to the returned
value in a function return statement (6.6.3) persists until the
function exits."  In other words, it's just like returning a local
auto variable, for the same reason.  The standard doesn't force a
compiler to communicate the fact that the reference returned by a
function is bound to a temporary so that the temporary can be
destroyed in the calling context.

--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/06/29
Raw View
James Shaw wrote:
>
> Hello everyone,
>
> I have a question regarding the C++ standard that came
> up while I was writing a new class today.
>
> I had the following two inline functions:
>
> inline const X & foo()
> {
>         X x(0, 0, 0);
>         // Do some stuff to x....
>         return x;                       // This generates a compiler warning.
> }
>
> inline const X & bar()
> {
>         return X(1, 2, 3);      // But this doesn't!
> }

1. Please include a definition for X, preferrably the simplest possible
definition that retains the confusing behavior.
2. Please include the exact text of compiler's warning message.
Note: a compiler is free to warn about anything it wants. It could warn
you about adding two integers together: "May overflow". Diagnostics are
required in some cases, but they're never prohibited.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "change" <uunet!changeme!changeme@ncar.UCAR.EDU>
Date: 1999/06/29
Raw View
I guess that it is compiler-specific. Because when I compiled these code. It
generated ERROR MESSAGE: "can not return a reference to a local variable or
temporary" instead of wanning.

Does anybody has better explanations?

Jack Chen
mailto:kefengchen@att.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jhs@entropy.cs.princeton.edu (James Shaw)
Date: 1999/06/30
Raw View
Hello everyone,

I am the original poster of the following allowed code fragment:
>inline const X & bar()
>{
> return X(1, 2, 3);
>}

It appears illegal in the standard. However, it was allowed without
warning by my compiler.  The following posters confirm its illegality:

Jack Chen wisely coded it up on his compiler and got an error message.
The most useful reply was by William Miller, who stated:

> It isn't [legal].  According to 12.2p5, "A temporary bound to the returned
> value in a function return statement (6.6.3) persists until the
> function exits."  In other words, it's just like returning a local
> auto variable, for the same reason.  The standard doesn't force a
> compiler to communicate the fact that the reference returned by a
> function is bound to a temporary so that the temporary can be
> destroyed in the calling context.

I have an old reference here (Stroustrup, 2nd edition, 1991) but
I'll take William's word on the above.

Many thanks, I'll switch my code to return X rather than const X &
in these cases.

Best,
James
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]