473,406 Members | 2,710 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Is f() lvalue?


Consider:

int g(){int b=1; return b;}

int main()
{
int d=2;
g()=d;
}
gcc compiler fails to compile it with 'non-lvalue in assignment' error
message, which I would expect.

However the following code happily compiles and executes:

struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
}
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?

Thanks,

Michael
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Jul 22 '05 #1
14 2972
> int g(){int b=1; return b;}
g()=d; struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
} Does it mean that f() is lvalue if f returns struct or class object, but not lvalue if f returns built-in type ....?


Yes, I think so.

I think a returned object is a lvalue (some say: value with location).
Obviously the returned object must have a location.
The int return-value of g is not a lvalue. It's just 1.

--
Marco

Jul 22 '05 #2
Michael Ovetsky wrote:
Consider:

int g(){int b=1; return b;}

int main()
{
int d=2;
g()=d;
}
gcc compiler fails to compile it with 'non-lvalue in assignment' error
message, which I would expect.

However the following code happily compiles and executes:

struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
}
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?


There's nothing wrong with the compiler. In both cases the returned
object is not an lvalue. The difference between the two is that in the
first case you are using built-in assignment operator and in the second
case you are using user-defined assignment operator (which in this case
is provided by the compiler as 'A& A::operator=(const A&)').

The built-in assignment operator requires an lvalue on the left-hand
side. That's why you get the error message.

The user-defined assignment operator has no such requirement and the
code compiles fine.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #3
>There's nothing wrong with the compiler. In both cases the returned
object is not an lvalue. The difference between the two is that in thefirst case you are using built-in assignment operator and in the secondcase you are using user-defined assignment operator (which in this caseis provided by the compiler as 'A& A::operator=(const A&)').


It still seems to me that gcc considers function call that returns
structure an lvalue.

The following code won't compile with "non-lvalue in unary `&'"
message.

int g(){int b=1; return b;}
int main()
{
&g();
}

However the following code will compile (albeit with "taking address
of temporary" warning)and execute:

struct A {int a;};
A f(){A b={1}; return b;}
int main()
{
&f();
}

I don't think that gcc uses user-defined A* operator&() in this case,
it just takes address of an object.

Michael Ovetsky
Jul 22 '05 #4
On 1 Nov 2004 09:23:08 -0800, MO******@ureach.com (Michael Ovetsky)
wrote:
There's nothing wrong with the compiler. In both cases the returned
object is not an lvalue. The difference between the two is that inthe
first case you are using built-in assignment operator and in the

second
case you are using user-defined assignment operator (which in this

case
is provided by the compiler as 'A& A::operator=(const A&)').


It still seems to me that gcc considers function call that returns
structure an lvalue.

The following code won't compile with "non-lvalue in unary `&'"
message.

int g(){int b=1; return b;}
int main()
{
&g();
}

However the following code will compile (albeit with "taking address
of temporary" warning)and execute:


The code is not well-formed, and the compiler is conforming in that it
outputs a diagnostic as required by the standard.
struct A {int a;};
A f(){A b={1}; return b;}
int main()
{
&f();
}

I don't think that gcc uses user-defined A* operator&() in this case,
it just takes address of an object.


Right, but the code isn't legal, since f() is an rvalue. You could
make it legal by explicitly overloading operator&, so you're back to
calling a member function on an rvalue, which is perfectly legal.

Tom
Jul 22 '05 #5
Michael Ovetsky wrote:
...
It still seems to me that gcc considers function call that returns
structure an lvalue.
No, it doesn't.
The following code won't compile with "non-lvalue in unary `&'"
message.

int g(){int b=1; return b;}
int main()
{
&g();
}

However the following code will compile (albeit with "taking address
of temporary" warning)and execute:

struct A {int a;};
A f(){A b={1}; return b;}
int main()
{
&f();
}

I don't think that gcc uses user-defined A* operator&() in this case,
it just takes address of an object.


The second example is also ill-formed. You are right, in this case the
built-in operator '&' is used. And it is used illegally, since the
result of 'f' is not an lvalue.

GCC compiler implements a moderately popular language extension that
allows this code to compile and issues a warning to inform you about
that fact. It is a little surprising that GCC still compiles this code
in '-ansi -pedantic' mode (although issuing a warning is already enough
to satisfy the standard requirement concerning diagnostic messages).
Comeau Online compiler rejects the code with an error message.

--
Best regards,
Andrey Tarasevich
Jul 22 '05 #6

Michael Ovetsky wrote:
Consider:

int g(){int b=1; return b;}

int main()
{
int d=2;
g()=d;
}
gcc compiler fails to compile it with 'non-lvalue in assignment' error
message, which I would expect.

However the following code happily compiles and executes:

struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
}
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?


It's an rvalue (not an lvalue) in either case, but you *can*
assign to an rvalue of class type (because assignment in that
case is just syntactic sugar for a call to the operator=
member function, and member functions can be used on rvalues).

This is one reason why in some situations it makes sense to
return UDT values as consts, whereas that is nonsensical for
builtin types.

-- James

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #7

Michael Ovetsky wrote:
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?


gcc is conformant, but the reason is not the one you describe.

First of all, §3.10/5 clearly says that "The result of calling a
function that does not return a reference is an rvalue." So f() returns
an rvalue in both cases (basic type and class type).

It's true that §5.17/1 says "[Assigment operators] requires a modifiable
lvalue as their left operand" but that statement only applies to the
built-in assignment operator, i.e. it's true only for basic types. For
class types §5.17/4 takes precedence: "Assignment to objects of a class
is defined by the copy assignment operator (12.8, 13.5.3)"

Because of §13.5.3, when f() is of class type f() = expr is interpreted
as f().operator=(expr). Here's the quirk: you *can* invoke a member
function even on an rvalue. Thus the expression f() = expr is legal.

I know that it's not very intuitive, but that's how it is. A sometimes
useful idiom is to return a const T instead of a T, as in that case the
compiler won't be able to call operator= because it operates only on
non-const objects.

HTH,

Alberto

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #8

Michael Ovetsky wrote:
<snip>
However the following code happily compiles and executes:

struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
}
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?


Neither. There is no prohibition against calling non-const members of
rvalues of class-type, so in general you can assign to them. For this
reason some authors recommend qualifying return types with 'const' if
they are class-types.

--
Ben Hutchings
Who are all these weirdos? - David Bowie, about L-Space IRC channel #afp

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #9

GCC is right. What happens is in case of struct, the struct's assignment
operator (implicitly defined) gets called. So, the line f()=c actually
reads: c.operator =(f()); which is okay and compiles.

BTW, if I used a C compiler for this, will f()=c compile ?

-Arijit

Michael Ovetsky <mo******@ureach.com> wrote in message news:<gN********************@comcast.com>...
Consider:

int g(){int b=1; return b;}

int main()
{
int d=2;
g()=d;
}
gcc compiler fails to compile it with 'non-lvalue in assignment' error
message, which I would expect.

However the following code happily compiles and executes:

struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
}
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #10

Michael Ovetsky wrote:
Consider:

int g(){int b=1; return b;}

int main()
{
int d=2;
g()=d;
}
gcc compiler fails to compile it with 'non-lvalue in assignment' error
message, which I would expect.

However the following code happily compiles and executes:

struct A {int a;};
A f(){A b={1}; return b;}

int main()
{
A c ={2};
f()=c;
}
Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of
C++ standard by gcc is one to blame?


There's nothing wrong with the compiler. In both cases the returned
object is not an lvalue. The difference between the two is that in the
first case you are using built-in assignment operator and in the second
case you are using user-defined assignment operator (which in this case
is provided by the compiler as 'A& A::operator=(const A&)').

The built-in assignment operator requires an lvalue on the left-hand
side. That's why you get the error message.

The user-defined assignment operator has no such requirement and the
code compiles fine.

--
Best regards,
Andrey Tarasevich
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #11

"Michael Ovetsky" <mo******@ureach.com> wrote in message
news:gN********************@comcast.com...
gcc compiler fails to compile it with 'non-lvalue in assignment' error
message, which I would expect. However the following code happily compiles and executes:
struct A {int a;};
A f(){A b={1}; return b;}
f()=c;

Does it mean that f() is lvalue if f returns struct or class object, but
not lvalue if f returns built-in type or incorrect implementation of


Return A from f() is rvalue. The rules allow member funcitons called on a
rvalue. A::operator = is a member funcion, so the code and the compiler is
correct.

You can return const A to avoid such assignment, or calling other nonconst
member functions.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Jul 22 '05 #12

On Mon, 1 Nov 2004 22:23:24 +0000 (UTC), Arijit wrote:

GCC is right. What happens is in case of struct, the struct's assignment
operator (implicitly defined) gets called. So, the line f()=c actually
reads: c.operator =(f()); which is okay and compiles.

BTW, if I used a C compiler for this, will f()=c compile ?


Not it would not compile in C. A modifiable lvalue is required as the
left hand operand of the assignment operator.

Try it here
http://www.comeaucomputing.com/tryitout/

struct A {int a;};
struct A f(){struct A b={1}; return b;}

int main()
{
struct A c ={2};
f()=c;
}

Graeme

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Jul 22 '05 #13

"Alberto Barbati" wrote:
[...]
It's true that §5.17/1 says "[Assigment operators] requires a modifiable
lvalue as their left operand" but that statement only applies to the
built-in assignment operator, i.e. it's true only for basic types. For
class types §5.17/4 takes precedence: "Assignment to objects of a class
is defined by the copy assignment operator (12.8, 13.5.3)"

Because of §13.5.3, when f() is of class type f() = expr is interpreted
as f().operator=(expr). Here's the quirk: you *can* invoke a member
function even on an rvalue. Thus the expression f() = expr is legal.
[...]


Also,

§3.10/2 "An lvalue refers to an object or function. Some rvalue
expressions--those of class or cv-qualified class type--also refer to
objects. 47)"

Footnote 47) "Expressions such as an invocations of constructors and of
functions that return a class type refer to objects, and the implementation
can invoke member functions upon such objects, but the expressions are not
lvalues."
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #14
Sam
operator (implicitly defined) gets called. So, the line f()=c actually
reads: c.operator =(f()); which is okay and compiles.

c.operator = (f());?
OR
f().operator = (c); ?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Jul 22 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: Hongzheng Wang | last post by:
In K&R, they said: An object is a named region of storage; an lvalue is an expression refer to an object. How about these concept in C++? `The C++ Programming Language' has a similar...
9
by: Steven T. Hatton | last post by:
This is from the draft of the previous version of the Standard: http://www.kuzbass.ru:8086/docs/isocpp/expr.html 2- A literal is a primary expression. Its type depends on its form...
15
by: Michael Baehr | last post by:
I recently upgraded my Arch Linux system to GCC 3.4, and found out that a previously accepted behavior (cast-as-lvalue) is now marked as deprecated, and will cease to function in GCC 3.5. This has...
24
by: Romeo Colacitti | last post by:
Hi, Does anyone here have a strong understanding for the meanings of the terms "lvalue" and "rvalue" as it pertains to C, objects, and different contexts? If so please share. I've been...
9
by: junky_fellow | last post by:
Consider the following piece of code: (char *)0x100; /* I know that converting an integer to pointer type is implementation defined. But forget this for a moment */ My question is, Why the...
3
by: Kavya | last post by:
Can someone give and explain in simple terms a definition of lvalue? Also what are these modifiable and non-modifiable lvalues? I always thought that, if we can assign to anything then that...
10
by: the_init | last post by:
Hi friends, I read about Lvalue in previous posting and Googled it but I'm not understood it completely. There is a small doubt. int a; a=20; // here a is Lvalue But
14
by: nobrow | last post by:
Yes I know what lvalue means, but what I want to ask you guys about is what are all valid lvalues ... a *a a *(a + 1) .... What else?
6
by: Yarco | last post by:
I've alway thought lvalue means Left Value and rvalue means Right Value before i've read someone's article. It is said "lvalue = location value" and "rvalue = read value". Which one is right, then?
33
by: Pietro Cerutti | last post by:
Hi group, assume the following declarations: char *func_1(void); void func_2(char **); I am allowed to do: char *c = func_1();
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.