lvalue difference between static and non static member functions

T

tkrogc

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
}
 
I

Ian Collins

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.
 
D

David Lindauer

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
 
K

Kai-Uwe Bux

Ian said:
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::eek: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
 
I

Ian Collins

David said:
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.
 
K

Kai-Uwe Bux

Kai-Uwe Bux said:
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::eek:fstream( "/dev/stdout" ) << "hello world!\n";

Hah! Tricked myself again. Should be:

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

Ian Collins

Kai-Uwe Bux said:
Ian Collins wrote:




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....
 
V

Victor Bazarov

Ian said:
[...] 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
 
T

Thomas Krog

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)
 
B

Ben Bacarisse

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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top