7

While looking into Can you have a incrementor and a decrementor on the same variable in the same statement in c

I discovered that you can have several prefix increment/decrement operators on a single variable, but only one postfix

ex:

++--++foo; // valid
foo++--++; // invalid
--foo++;   // invalid

Why is this?

user207421
  • 305,947
  • 44
  • 307
  • 483
Ashterothi
  • 3,282
  • 1
  • 21
  • 35

2 Answers2

10

This is due to the fact that in C++ (but not C), the result of ++x is a lValue, meaning it is assignable, and thus chain-able.

However, the result of x++ is NOT an lValue, instead it is a prValue, meaning it cannot be assigned to, and thus cannot be chained.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
6

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Can you show some documentation that says that the result is undefined? Seems to me like it should be completely well-defined (evaluated right-to-left outwards). – Richard J. Ross III Jul 26 '12 at 23:37
  • @RichardJ.RossIII UB because *(C++11, 1.9p15) "If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined."* – ouah Jul 26 '12 at 23:41
  • @Richard J. Ross III: The well-known paragraph 5/4 in C++ language specification (C++98, C++03). It is illegal (in UB sense) to modify the same object twice without intervening *sequence point* (SP). C++ does not define order of evaluation for built-in operators without SP. There's no such thing as "evaluated left-to-right" in C++ without SP. Any orderings require intervening SP. There's no sequence point in `++--foo`, hence the behavior is undefined. C++11 uses a different formal approach to sequencing, but the basic principle remains the same. – AnT stands with Russia Jul 26 '12 at 23:41