Topic: Is f() lvalue?
Author: Sam <manseesaw@hotmail.com>
Date: Fri, 19 Nov 2004 15:37:48 +0000 (UTC) Raw View
> 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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Michael Ovetsky <movetsky@ureach.com>
Date: Sun, 31 Oct 2004 14:29:14 +0000 (UTC) Raw View
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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Alberto Barbati <AlbertoBarbati@libero.it>
Date: Mon, 1 Nov 2004 22:23:24 +0000 (UTC) Raw View
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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Mon, 1 Nov 2004 22:23:24 +0000 (UTC) Raw View
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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: pal_ari@yahoo.co.in (Arijit)
Date: Mon, 1 Nov 2004 22:23:24 +0000 (UTC) Raw View
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 <movetsky@ureach.com> wrote in message news:<gNedndfXLZ1zqhncRVn-iA@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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Ben Hutchings <ben-public-nospam@decadentplace.org.uk>
Date: Mon, 1 Nov 2004 22:23:25 +0000 (UTC) Raw View
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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Andrey Tarasevich <andreytarasevich@hotmail.com>
Date: Mon, 1 Nov 2004 22:23:25 +0000 (UTC) Raw View
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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Graeme Prentice <gprenz@hotmail.com>
Date: Tue, 2 Nov 2004 15:26:43 +0000 (UTC) Raw View
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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Balog Pal <pasa@lib.hu>
Date: Tue, 2 Nov 2004 15:26:43 +0000 (UTC) Raw View
"Michael Ovetsky" <movetsky@ureach.com> wrote in message
news:gNedndfXLZ1zqhncRVn-iA@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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Marlene Miller <marlenemiller@worldnet.att.net>
Date: Fri, 5 Nov 2004 17:28:21 +0000 (UTC) Raw View
"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:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]