Search code examples
c++operatorslvaluepost-incrementpre-increment

Why is "++i++" invalid while (++i)++ is valid?


Let's consider the following code:

int main() {
    int i = 2;
    int b = ++i++;
    return 3;
}

It compiles with the following with an error:

<source>: In function 'int main()':

<source>:3:16: error: lvalue required as increment operand

    3 |     int b = ++i++;

      |                ^~

This sounds fair to me. Postfix increment has higher priority than prefix increment, so the code is parsed as int b = ++(i++); and i is an rvalue. Hence the error.

Let's now consider this variant with parenthesis to override default priorities:

int main() {
    int i = 2;
    int b = (++i)++;
    return 3;
}

This code compiles and returns 3. On its own, this sounds fair to me but it seems in contradiction with the first code.

The question: why (++i) is an lvalue when i is not?

Thanks!

UPDATE: the error message shown above was from gcc (x86-64 9.2). Here is the exact rendering: error with gcc

Clang x86-64 9.0.0 has a quite different message: error with clang

<source>:3:13: error: expression is not assignable

    int b = ++i++;

            ^ ~~~

With GCC, you get the impression that the problem is with the postfix operator and you can then wander why ++i is OK while i is not, hence my question. With Clang it is clearer that the problem is with the prefix operator.


Solution

  • i and ++i are both lvalues, but i++ is an rvalue.

    ++(i++) cannot be valid, as the prefix ++ is being applied to i++, which is an rvalue. But (++i)++ is fine because ++i is an lvalue.

    Note that in C, the situation is different; i++ and ++i are both rvalues. (This is an example of why people should stop assuming that C and C++ have the same rules. People insert these assumptions into their questions, which must then be refuted.)