Topic: rvalues and reference arguments
Author: steve@lia.com (Stephen Williams)
Date: Tue, 6 Dec 1994 01:16:04 GMT Raw View
In article <craigaD0424o.AFI@netcom.com> craiga@netcom.com (Craig Arnush) writes:
yergeau@outpost.Stanford.EDU (Dan Yergeau) writes:
>
>Is the following legal?
>
> void foo( int& i )
> {
> printf( "%d", i );
> }
>
> main()
> {
> foo( 2 );
> }
Think "temporary objects". What you get is a temorary int being created
for the sole purpose of passing in a reference. You can go ahead and
muck with the contents of the temporary object via the reference inside of
foo(), but of course main() doesn't make use of that.
Me
I believe the draft currently states that temporaries are const. The
temporary thus may be passed as const&, but not by reference. The GNU
compiler certainly complains, and I believe that cfront 3.* compilers
also printed at least a warning.
In short, it is not just meaningless to pass a temporary by nonconst
reference, it is an error.
Caveat: this is from memory.
--
Stephen 2. Williams
Work: steve@lia.com
Home: steve@icarus.com
Fight License Managers! Buy from
vendors who use honor system!
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Tue, 6 Dec 1994 15:21:31 GMT Raw View
In article <STEVE.94Dec5171605@spokane.LIA.COM> steve@lia.com (Stephen Williams) writes:
>
>I believe the draft currently states that temporaries are const. The
>temporary thus may be passed as const&, but not by reference.
Sorry. A temporary created by a constructor or
function returning a value not specified const is non-const.
While only a const reference ( and now, it is clarified,
NOT a const volatile ref) may bind to the temporary as an 'ordinary'
argument, the temporary used as the object of a member function call
acts as if an lvalue of the qualified type. For example:
f(X&);
f(X()); //error
X()=X(); // fine, because X() is non-const
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd,
81A Glebe Point Rd, GLEBE Mem: SA IT/9/22,SC22/WG21
NSW 2037, AUSTRALIA Phone: 61-2-566-2189
Author: yergeau@outpost.Stanford.EDU (Dan Yergeau)
Date: 30 Nov 1994 23:09:43 GMT Raw View
Is the following legal?
void foo( int& i )
{
printf( "%d", i );
}
main()
{
foo( 2 );
}
Most compilers seem to accept it without any concern, but g++ (2.6.0)
gives a warning (and rightly so, IMHO).
Author: craiga@netcom.com (Craig Arnush)
Date: Thu, 1 Dec 1994 02:41:11 GMT Raw View
yergeau@outpost.Stanford.EDU (Dan Yergeau) writes:
>
>Is the following legal?
>
> void foo( int& i )
> {
> printf( "%d", i );
> }
>
> main()
> {
> foo( 2 );
> }
>
>Most compilers seem to accept it without any concern, but g++ (2.6.0)
>gives a warning (and rightly so, IMHO).
>
>From what I've seen in the ARM, this doesn't seem to be officially
>sanctioned, but it doesn't seem to be explicitly forbidden either.
Think "temporary objects". What you get is a temorary int being created
for the sole purpose of passing in a reference. You can go ahead and
muck with the contents of the temporary object via the reference inside of
foo(), but of course main() doesn't make use of that.
Me
Author: sdouglass@armltd.co.uk (scott douglass)
Date: 1 Dec 1994 10:41:17 GMT Raw View
In article <1994Nov30.141726@outpost.Stanford.EDU>,
yergeau@outpost.Stanford.EDU (Dan Yergeau) wrote:
> Is the following legal?
>
> void foo( int& i )
> {
> printf( "%d", i );
> }
>
> main()
> {
> foo( 2 );
> }
>
> Most compilers seem to accept it without any concern, but g++ (2.6.0)
> gives a warning (and rightly so, IMHO).
>
> From what I've seen in the ARM, this doesn't seem to be officially
> sanctioned, but it doesn't seem to be explicitly forbidden either.
No, it's not legal, but it used to be. The ARM says, on page 154
(8.4.3): [This is actually the text from the May WP but it is essentially
the same.]
"If the initializer for a reference to type T is an lvalue of type T or of
a type dervied from T for which T is an unambiguous accessible base class,
the reference will refer to the (T part of the) initializer; otherwise, if
and only if the reference is to a const and an object of type T can be
created from the initializer, such an object will be created. The
reference then becomes a name for that object."
'2' is not a lvalue and the parameter is not a reference to a const so the
call 'foo(2)' is illegal. Any compiler that allows it is probably doing
so to be nice to existing code. They should definitely give warnings.
They'll have to give errors to conform to the standard (when there is
one).
The following example appears in the WP:
double& rd2 = 2.0; // error: not an lvalue
--scott
Author: craiga@netcom.com (Craig Arnush)
Date: Thu, 1 Dec 1994 23:21:08 GMT Raw View
sdouglass@armltd.co.uk (scott douglass) writes:
>In article <1994Nov30.141726@outpost.Stanford.EDU>,
>yergeau@outpost.Stanford.EDU (Dan Yergeau) wrote:
>> Is the following legal?
>>
>> void foo( int& i )
>> {
>> printf( "%d", i );
>> }
>>
>> main()
>> {
>> foo( 2 );
>> }
So, placing changing the function definition to "void foo(const int&)"
would allow things to work? (Just making sure.) IMHO, this definitely
deserves to be a warning, but I'm not sure it's drastic enough to be
illegal. Just make the temporary object and be on your way.
Me
Author: rubenst%occs.nlm.nih.gov (Mike Rubenstein Phoenix Contract)
Date: Sat, 3 Dec 94 23:57:00 GMT Raw View
Dan Yergeau (yergeau@outpost.Stanford.EDU) wrote:
> Is the following legal?
> void foo( int& i )
> {
> printf( "%d", i );
> }
> main()
> {
> foo( 2 );
> }
> Most compilers seem to accept it without any concern, but g++ (2.6.0)
> gives a warning (and rightly so, IMHO).
> From what I've seen in the ARM, this doesn't seem to be officially
> sanctioned, but it doesn't seem to be explicitly forbidden either.
According to the ARM (8.4.3) this is an error:
If the initializer [argument passing is an initialization] for a
reference to type T is an lvalue of type T or of a type derived
from T for which T is an accessible base, the reference will refer
to the initializer; otherwise, if and olny if the reference is to a
const an object of type T will be created and initialized with the
initializer. The reference then becomes a name for that object.
I don't have the DWP here, but I'm pretty sure this has not changed.
--
Mike Rubenstein