I've got a longer answer here, but basically C11 draft n1570 6.3.2.1p1:
An lvalue is an expression (with an object type other than void) that potentially designates an object [...]
C11 n1570 Footnote 64:
64) The name lvalue comes originally from the assignment expression E1 = E2
, in which the left operand E1
is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object locator value. What is sometimes called rvalue is in this International Standard described as the value of an expression. An obvious example of an lvalue is an identifier of an object. As a further example, if E
is a unary expression that is a pointer to an object, *E
is an lvalue that designates the object to which E
points.
Not all lvalues are modifiable, i.e. can appear on the left side of an assignment. Examples of unmodifiable lvalues are those that
- have array type,
- have incomplete type
- are const-qualified
struct
s or union
s that have const
-qualified members either directly or recursively
An lvalue can be converted to a value of an expression through lvalue conversion. I.e. in
int a = 0, b = 1;
a = b;
both a
and b
are lvalues, as they both potentially - and actually - designate objects, but b
undergoes lvalue conversion on the right-hand side of the assignment, and the value of the expression b
after lvalue conversion is 1
.
"Potentially designating an object" means that given int *p;
, *p
designates an object of type int
iff p
points to an object of type int
- but *p
is an lvalue even if p == NULL
or indeterminate.