l-values are values that are defined after they are executed (++x
)
r-values are values that are not defined after they are executed (x++
)
No, that's not correct.
The words "lvalue" and "rvalue" (that's how the C standard spells them) have a long history. The terms come from 'l' for "left" and 'r' for "right", referring to the left and right sides of an assignment.
In some contexts, an expression may be either evaluated for its lvalue or evaluated for its rvalue. Given those definitions of the terms, an "rvalue" is what you'd normally think of as the value of an expression; evaluating 2+2
yields 4
. Evaluating an expression for its lvalue meant determining what object it refers to. For example, given:
int x;
x = 2 + 2;
the right side of the assignment, 2 + 2
would be evaluated for its rvalue, yielding 4
, and the left side would be evaluated for its lvalue, which means determining the object to which it refers. (The rvalue of the expression is not evaluated; the value previously stored in x
, if any, is not used.)
The C standard defines them differently. In C, an lvalue is not a value; it's a kind of expression. Specifically, quoting the 2011 ISO C standard, section 6.3.2.1:
An lvalue is an expression (with an object type other than void) that
potentially designates an object; if an lvalue does not designate an
object when it is evaluated, the behavior is undefined.
(The word "potentially" was added to cover cases like *ptr
, where ptr
is a pointer object; if ptr == NULL
then *ptr
doesn't currently designate an object, but it's still an lvalue. You can always determine at compile time whether a given expression is an lvalue or not. Earlier editions of the C standard had flawed definitions for lvalue.)
So basically an lvalue in C is an expression that designates an object. You can think of it as an expression that can appear on the left side of an assignment, though that's not entirely accurate; for example, the name of a const
object can't be on the LHS of an assignment, but it's still an lvalue. (As you can see, nailing down a precise and consistent definition for lvalue can be tricky.)
Neither x++
nor ++x
is an lvalue in C.
The C standard doesn't use the term rvalue beyond mentioning it in a single footnote:
What is sometimes called "rvalue" is in this International Standard
described as the "value of an expression".
So, as C defines the terms, an lvalue is a kind of expression (something that exists in C source code), but an rvalue is the result of evaluating an expression (something that exists during program execution).
(C++ has different rules, and several other classes of lvalue-like things, including glvalues and so forth. I won't get into that here.)