Why does C++ accept multiple prefixes but not postfixes for a variable
Asked Answered
K

2

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?

Ketone answered 26/7, 2012 at 23:28 Comment(0)
S
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.

Shelf answered 26/7, 2012 at 23:32 Comment(0)
A
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.

Alleviation answered 26/7, 2012 at 23:32 Comment(3)
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).Shelf
@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."Crouse
@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.Alleviation

© 2022 - 2024 — McMap. All rights reserved.