@AndyProwl: I always avoid using more preincrement/postincrement operations within the same line... I don't want to end up with something like this: b = ++a + ++a;, which is already UB as far as I know.
–
LihOFeb 10 '13 at 14:57

1

I think the real lesson to understand is that fewer lines of C code do not make a faster program. It would be better to write 2 or 3 lines instead. Its more obvious and easier to understand. I'd recommend only using predecrement/increment and only use post decrement/increment for very special situations (i.e. you can't figure out any other way to write it).
–
Josh PetittFeb 10 '13 at 15:32

In C and C++, there are lvalue expressions which may be used on the left-hand side of the = operator and rvalue expressions which may not. C++ allows more things to be lvalues because it supports reference semantics.

++ a = 3; /* makes sense in C++ but not in C. */

The increment and decrement operators are similar to assignment, since they modify their argument.

In C++03, (++a)-- would cause undefined behavior because two operations which are not sequenced with respect to each other are modifying the same variable. (Even though one is "pre" and one is "post", they are unsequenced because there is no ,, &&, ?, or such.)

In C++11, the expression now does what you would expect. But C11 does not change any such rules, it's a syntax error.

For anybody who might want the precise details of the differences as they're stated in the standards, C99, §6.5.3/2 says:

The value of the operand of the prefix ++ operator is incremented. The result is the new
value of the operand after incrementation.

By contrast, C++11, §5.3.2/1 says:

The result is the updated operand; it is an lvalue, and it is a bit-field if
the operand is a bit-field.

[emphasis added, in both cases]

Also note that although (++a)-- gives undefined behavior (at least in C++03) when a is an int, if a is some user-defined type, so you're using your own overloads of ++ and --, the behavior will be defined -- in such a case, you're getting the equivalent of:

a.operator++().operator--(0);

Since each operator results in a function call (which can't overlap) you actually do have sequence points to force defined behavior (note that I'm not recommending its use, only noting that the behavior is actually defined in this case).