Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > lvalue difference between static and non static member functions

Reply
Thread Tools

lvalue difference between static and non static member functions

 
 
tkrogc@gmail.com
Guest
Posts: n/a
 
      02-05-2006
I compiled the source below using the comeau compiler
http://www.comeaucomputing.com/tryitout/
Why does the f funtion compile while the g function produces an lvalue
error ?
(I thought the two functions were identical except for a harmless
syntax difference)

struct A
{
void f(){}
static void g(A& a){}
};
int main()
{
A().f();
A::g(A()); // must be an lvalue
}

 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      02-05-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I compiled the source below using the comeau compiler
> http://www.comeaucomputing.com/tryitout/
> Why does the f funtion compile while the g function produces an lvalue
> error ?
> (I thought the two functions were identical except for a harmless
> syntax difference)
>
> struct A
> {
> void f(){}
> static void g(A& a){}
> };
> int main()
> {
> A().f();
> A::g(A()); // must be an lvalue
> }
>

You are passing a non-const reference to a temporary object (which
doesn't make sense - what happens if you change it?), you should either
declare g taking a const A&, or pass a real A.

--
Ian Collins.
 
Reply With Quote
 
 
 
 
David Lindauer
Guest
Posts: n/a
 
      02-05-2006


(E-Mail Removed) wrote:

> I compiled the source below using the comeau compiler
> http://www.comeaucomputing.com/tryitout/
> Why does the f funtion compile while the g function produces an lvalue
> error ?
> (I thought the two functions were identical except for a harmless
> syntax difference)
>
> struct A
> {
> void f(){}
> static void g(A& a){}
> };
> int main()
> {
> A().f();
> A::g(A()); // must be an lvalue
> }


The error isn't related to the functions... what it is complaining about
is the fact that A() is not an lvalue, but you are using it to initialize
a non-const reference variable (in this case a parameter). Why it would
do that I don't know... the compiler I use allows such things by liberally
creating temporary variables on an as-needed basis, then using the lvalue
of the temp.

I would like to hear if the comeau behavior is standard behavior, but
meanwhile you can fix it by changing the declaration of g as follows:

static void g(const A& a);

David

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      02-05-2006
Ian Collins wrote:

> (E-Mail Removed) wrote:
>> I compiled the source below using the comeau compiler
>> http://www.comeaucomputing.com/tryitout/
>> Why does the f funtion compile while the g function produces an lvalue
>> error ?
>> (I thought the two functions were identical except for a harmless
>> syntax difference)
>>
>> struct A
>> {
>> void f(){}
>> static void g(A& a){}
>> };
>> int main()
>> {
>> A().f();
>> A::g(A()); // must be an lvalue
>> }
>>

> You are passing a non-const reference to a temporary object (which
> doesn't make sense - what happens if you change it?),


Well, it makes sense. With all objects, changes occur only during the
lifetime of the object. That this lifetime is short (in the case of a
temporary), does not change anything. In fact, think of a file stream.
Clearly you could write stuff to the file while it exists. Once the
temporary file stream dies, the file closes and the changes are now on your
hard disk:

#include <iomanip>
#include <fstream>

int main ( void ) {

std:fstream( "/dev/stdout" ) << "hello world!\n";

}

Note that this works, since you can call non-const member functions of
temporary objects.

However, although it makes sense to modify a temporary, the standard simply
forbids passing a non-const reference to a temporary. I never found a
convincing rational.


> you should either declare g taking a const A&, or pass a real A.


Correct.


Best

Kai-Uwe Bux
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      02-05-2006
David Lindauer wrote:
> The error isn't related to the functions... what it is complaining about
> is the fact that A() is not an lvalue, but you are using it to initialize
> a non-const reference variable (in this case a parameter). Why it would
> do that I don't know... the compiler I use allows such things by liberally
> creating temporary variables on an as-needed basis, then using the lvalue
> of the temp.
>
> I would like to hear if the comeau behavior is standard behavior, but
> meanwhile you can fix it by changing the declaration of g as follows:
>

It is. Several compilers (mine included) do as yours does, but they
shouldn't.

--
Ian Collins.
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      02-05-2006
Kai-Uwe Bux wrote:

> Ian Collins wrote:
>
>> (E-Mail Removed) wrote:
>>> I compiled the source below using the comeau compiler
>>> http://www.comeaucomputing.com/tryitout/
>>> Why does the f funtion compile while the g function produces an lvalue
>>> error ?
>>> (I thought the two functions were identical except for a harmless
>>> syntax difference)
>>>
>>> struct A
>>> {
>>> void f(){}
>>> static void g(A& a){}
>>> };
>>> int main()
>>> {
>>> A().f();
>>> A::g(A()); // must be an lvalue
>>> }
>>>

>> You are passing a non-const reference to a temporary object (which
>> doesn't make sense - what happens if you change it?),

>
> Well, it makes sense. With all objects, changes occur only during the
> lifetime of the object. That this lifetime is short (in the case of a
> temporary), does not change anything. In fact, think of a file stream.
> Clearly you could write stuff to the file while it exists. Once the
> temporary file stream dies, the file closes and the changes are now on
> your hard disk:
>
> #include <iomanip>
> #include <fstream>
>
> int main ( void ) {
>
> std:fstream( "/dev/stdout" ) << "hello world!\n";


Hah! Tricked myself again. Should be:

std:fstream( "/dev/stdout" ) << std::dec << "hello world!\n";

> }
>
> Note that this works, since you can call non-const member functions of
> temporary objects.
>
> However, although it makes sense to modify a temporary, the standard
> simply forbids passing a non-const reference to a temporary. I never found
> a convincing rational.
>
>
>> you should either declare g taking a const A&, or pass a real A.

>
> Correct.
>
>
> Best
>
> Kai-Uwe Bux


 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      02-06-2006
Kai-Uwe Bux wrote:
> Ian Collins wrote:
>
>
>>(E-Mail Removed) wrote:
>>
>>>I compiled the source below using the comeau compiler
>>>http://www.comeaucomputing.com/tryitout/
>>>Why does the f funtion compile while the g function produces an lvalue
>>>error ?
>>>(I thought the two functions were identical except for a harmless
>>>syntax difference)
>>>
>>>struct A
>>>{
>>> void f(){}
>>> static void g(A& a){}
>>>};
>>>int main()
>>>{
>>> A().f();
>>> A::g(A()); // must be an lvalue
>>>}
>>>

>>
>>You are passing a non-const reference to a temporary object (which
>>doesn't make sense - what happens if you change it?),

>
>
> Well, it makes sense. With all objects, changes occur only during the
> lifetime of the object. That this lifetime is short (in the case of a
> temporary), does not change anything. In fact, think of a file stream.
> Clearly you could write stuff to the file while it exists. Once the
> temporary file stream dies, the file closes and the changes are now on your
> hard disk:
>

Yes, I know it was a lame explanation, but it was the best I could come
up with. I've never fully understood this. Caused me all sorts of
grief porting code from a compiler that ignores the rule to one that
enforces it....

--
Ian Collins.
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      02-06-2006
Ian Collins wrote:
> [...] I've never fully understood this. Caused me all sorts
> of grief porting code from a compiler that ignores the rule to one
> that enforces it....


D&E, page 82, IIRC. Or 86. I guess I don't RC...

V
--
Please remove capital As from my address when replying by mail


 
Reply With Quote
 
Thomas Krog
Guest
Posts: n/a
 
      02-06-2006
Sorry I do not feel my question has been completely answered. I am not
looking for a work-around to the compiler error. I am asking why they
chose to design the language such that the f function call does compile
while the g function call does not.

(if the answer is in D&E I will be happy to hear about it)

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-06-2006
On Mon, 06 Feb 2006 01:54:41 -0800, Thomas Krog wrote:

> Sorry I do not feel my question has been completely answered. I am not
> looking for a work-around to the compiler error. I am asking why they
> chose to design the language such that the f function call does compile
> while the g function call does not.
>
> (if the answer is in D&E I will be happy to hear about it)


I can give you half and answer... My 1990 (has it really been that long?)
copy of the Annotated C++ Reference Manual (sec 8.4.3 p 155) says:

The distinction was made to eliminate a major source of errors and
surprises. Earlier, all references could be initialized to refer to
temporary objects...

The other half, examples of the major errors and surprises, escapes me.
Anyone?

--
Ben.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
overloading non-template member functions with template member functions Hicham Mouline C++ 1 04-24-2009 07:47 AM
overloading non-template member functions with template member functions Hicham Mouline C++ 0 04-23-2009 11:42 AM
using a method as an lvalue and "invalid lvalue in assignment"compilation error markryde@gmail.com C Programming 11 09-22-2008 10:42 AM
operators requiring lvalue/rvalue operands and resulting in rvalue/lvalue Kavya C Programming 9 10-28-2006 01:45 AM
Perl hangs when returning lvalue closure from another lvalue closure Julian Mehnle Perl Misc 0 07-17-2003 03:13 PM



Advertisments