A function call returning a structure is an rvalue expression, but what about its members?
This piece of code works well with my g++ compiler, but gcc gives a error saying "lvalue required as left operand of assignment":
struct A { int v; }; struct A fun() { struct A tmp; return tmp; } int main() { fun().v = 1; }
gcc treats fun().v
as rvalue, and I can understand that.
But g++ doesn't think the assignment expression is wrong. Does that mean fun1().v is lvalue in C++?
Now the problem is, I searched the C++98/03 standard, finding nothing telling about whether fun().v
is lvalue or rvalue.
So, what is it?
An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.
An lvalue refers to an object that persists beyond a single expression. An rvalue is a temporary value that does not persist beyond the expression that uses it.
By default, the compiler cannot bind a non-const or volatile lvalue reference to an rvalue.
lvalues are “left values”: expressions that can be assigned to, which can be on the left of an assignment. rvalues are “right values”: everything else, which must be on the right of an assignment.
A member of an rvalue expression is an rvalue.
The standard states in 5.3.5 [expr.ref]:
If E2 is declared to have type “reference to T”, then E1.E2 is an lvalue [...] - If E2 is a non-static data member, and the type of E1 is “cq1 vq1 X”, and the type of E2 is “cq2 vq2 T”, the expression designates the named member of the object designated by the first expression. If E1 is an lvalue, then E1.E2 is an lvalue.
Edit: Ok, I guess I finally have something from the standard:
Note that v
is of type int
which has an built-in assignment operator:
13.3.1.2 Operators in expressions
4 For the built-in assignment operators, conversions of the left operand are restricted as follows: — no temporaries are introduced to hold the left operand, and [...]
fun1()
should return a reference. A non-reference/pointer return type of a function is a r-value.
3.10 Lvalues and rvalues
5 The result of calling a function that does not return an lvalue reference is an rvalue [...]
Thusly, fun1().v
is a rvalue.
8.3.2 References
2 A reference type that is declared using & is called an lvalue reference, and a reference type that is declared using && is called an rvalue reference. Lvalue references and rvalue references are distinct types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With