What is the reasoning behind the naming of \"lvalue\" and \"rvalue\" in C/C++ (I know how they function)?
The 'l' in lvalue originated from 'left' value (as in from the left-hand side of the assignment operator); however, it now stands for location value, and refers to any object that occupies some identifiable location in memory (i.e. has an address). An rvalue is now anything that is not an lvalue.
The standard mentions this:
An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment expression) [...]
An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) [...]
That is, an lvalue was something you could assign to and an rvalue was something you could assign from.
However, this has gradually gotten further and further from the truth. A simple example of an lvalue that you can't assign it is a const
variable.
const int x = 5;
x = 6; // Error
You can even have an rvalue appear on the left side of an assignment when you involve operator overloading.
I find it more useful to think of an lvalue as referencing an object stored in memory and an rvalue as just a value (that may have been read from memory). The concepts mirror this idea quite well. Some examples:
&
) requires an lvalue because you can only take the address of something in memory. It doesn't need to get the value of the object to work out its address.std::move
to turn an lvalue expression into an rvalue expression can be thought of as tricking the compiler into thinking the object that's stored in memory is actually just a temporary value.However, this also doesn't hold up in every situation. It's just a reasonable analogy.
In C, lvalue
and rvalue
reflect the usage in the assignment operator. rvalue
can appear only to the right of =
, while lvalue
can be on either side. In C++ it's similar, but more complicated.
There are non-assignable lvalues
, constant variables.
It's pretty intuitive if you think about what side of an assignment operator they can appear:
left-value = right-value;
Loosely put, lvalue
means you can assign to it, rvalue
means it can only appear on the right hand side of the operator.
Back in the olden days, an "lvalue" meant something that could go on the left side of an assignment, and an "rvalue" meant something that could go on the right side of an assignment.
This is the result of the simplification of a (somewhat more complex) concept.
lvalue
s are left values, i. e. those which "can be on the left side of an assignment". This is, again, a simplification, not all lvalues can be directly assigned to as-is (for example, arrays can't, only elements of a non-const
arrays, so subscripting is required).
rvalues
are right values, those which can only be on the right side of an assignment expression.