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.
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.)