You are misinterpreting GCC's error message:
<source>:5:8: error: lvalue required as increment operand
Note where the error message is pointing: the postfix++ part.
The token sequence
++i++ will, by C/C++'s operator precedence rules, be interpreted as
++(i++). So the postfix++ happens first.
The postfix++ operator does two things. It returns the current value of the operand and it increments the operand... in that order (conceptually). This means that, when
i++ returns something, what it returns is not
i. It has no relationship to
i. It's not a variable; it's just an
The ++prefix operator is defined to do two things: increment the operand it is given and return the operand... in that order (again, conceptually).
Here's the thing though: incrementing an operand requires that the operand is a variable (or a reference in C++). That is, the operand must be a thing that is assignable, that can go on the lefthand side of an assignment. Thus, such a thing is called a "lvalue".
You cannot call either increment operator on something that isn't an lvalue. It simply doesn't make sense. It's about as reasonable as wanting to do
5 += 3; you cannot change the value of 5. You can compute
5 + 3, but you're not changing the value of 5 or 3. You are computing a new value, which is neither 5 nor 3. Such values cannot appear on the lefthand side of an assignment; they can only appear on the righthand side. Thus, they are called "rvalues".
Postfix++ returns an rvalue. It must return an rvalue, because that is the nature of the operation. Remember: by the time postfix++ is done, the lvalue has been changed. But the result of the expression is the previous value. Therefore, that value must be a new value, divorced from the variable that was used to generate it. There is no variable which holds this value; therefore, what postfix++ generates is an rvalue.
And you cannot increment an rvalue expression. This is why
++5 does not work. And
++(i++) does not work for the same reason.
This is all necessary by the nature of what postfix++ means. The only way to change this would be to make postfix++ return an lvalue. But the only lvalue it has is its operand. And by the time an expression that consumes postfix++ sees the resulting lvalue, that variable will have been changed.
And that would make postfix++ behave exactly like ++prefix. So there would be no reason to have both.
There's no way around it. If you want postfix++ to actually do what postfix++ does, then
++i++ must be nonsensical code.
Now, could you redefine the meaning of assignment-like operations, so that you could make
5 += 3 simply become the equivalent of
5 + 3? That is, assignment to rvalues simply computes a new value (
5 = 3 evaluates to the expression
3). In theory, yes.
However, if a user writes something like
++(i++), you need to ask yourself a question: what did they intend to have happen?
If I pretend not to know much about C++, when I see that expression, I would expect the value of
i to be incremented twice, and that the result of the expression will be the current value of
i. But that's not what would happen under those rules. The
i++ part would return the original value of
i (which again, is why postfix++ exists to begin with). So the ++prefix will increment this value, resulting in
i only being incremented once. And the result would be the original value incremented once.
5 += 3 becoming
5 + 3 seems weird. That looks like a case of the compiler saying, "What you said doesn't make sense, so I'm going to guess at what you meant to say." And that's always a dangerous road to walk.