In C++ language prefix increment/decrement operators return lvalues, while postfix ones return rvalues. Meanwhile, all modifying operators require lvalue arguments. This means that the result of prefix increment/decrement can be passed on to any other additional operator that requires an lvalue argument (including additional increments/decrements).
For the very same reason in C++ you can write code like this
int i = 0;
int *p = &++i;
which will increment i
and make p
point to i
. Unary &
requires lvalue operand, which is why it will work with the result of prefix ++
(but not with postfix one).
Expressions with multiple built-in prefix increments/decrements applied to the same object produce undefined behavior, but they are nevertheless well-formed (i.e. "compilable").
Expressions like ++foo--
are invalid because in C++ postfix operators have higher precedence than prefix ones. Braces can change that. For example, (++foo)--
is a well-formed expression, albeit leading to undefined behavior again.