C11 6.5.3.1p1:
- The operand of the prefix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.
What this means is that if we have a construct something ++
, then something
- must be real: integral or floating point, but cannot be a complex number
- or can be of a pointer type (but a void pointer does not do because it does not have arithmetic defined)
- it can be also
_Atomic
or volatile
- but it must be an lvalue, i.e. designate an object that is modified by the increment
- and that lvalue must be modifiable (for example it cannot be
const
qualified)
The expression
a + b
is not an lvalue expression, it does not designate an object. It is an arithmetic expression; and the value of an arithmetic expression is not an lvalue. While you can add 1 to that value, the value of an expression is not an object to modify.
However, given
int a, *b, c[5][6];
struct FOO { char *bar; } foo, *fooz;
double *funnyfunc(int x);
all these expressions are modifiable scalar lvalues:
a
*(b + 5)
c[1][4]
foo.bar
fooz->bar
funnyfunc(5)[42]
and you can apply ++
to them.
There is one more problem with
c = (a + b) ++
the value of the post-increment expression is the value before increment, i.e. even if that a + b
were modifiable, c
would not have value a + b + 1
but a + b
anyway; and the a + b
would change its stored value for subsequent evaluations.