c++ operators lvalue post-increment pre-increment

c++ - ¿Por qué "++ i++" no es válido mientras que(++ i)++ es válido?



operators lvalue (3)

Consideremos el siguiente código:

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

Se compila con lo siguiente con un error:

<source>: In function ''int main()'': <source>:3:16: error: lvalue required as increment operand 3 | int b = ++i++; | ^~

Esto me parece justo. El incremento de postfix tiene mayor prioridad que el incremento de prefijo, por lo que el código se analiza como int b = ++(i++); y i es un valor De ahí el error.

Consideremos ahora esta variante con paréntesis para anular las prioridades predeterminadas:

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

Este código compila y devuelve 3. Por sí solo, esto me parece justo, pero parece estar en contradicción con el primer código.

La pregunta: ¿por qué (++i) es un valor i cuando no lo soy?

¡Gracias!

ACTUALIZACIÓN: el mensaje de error que se muestra arriba era de gcc (x86-64 9.2). Aquí está la representación exacta: error con gcc

Clang x86-64 9.0.0 tiene un mensaje bastante diferente: error con clang

<source>:3:13: error: expression is not assignable int b = ++i++; ^ ~~~

Con GCC, tiene la impresión de que el problema está en el operador de postfix y luego puede preguntarse por qué ++i está bien mientras no lo esté, de ahí mi pregunta. Con Clang es más claro que el problema está en el operador de prefijo.


entonces el código se analiza como int b = ++ (i ++); y yo es un valor

No. No soy un valor. Soy un valor. i++ es un rvalue (prvalue para ser específico).


Esta declaración

int b = ++i++;

es equivalente a

int b = ++( i++ );

El operador de incremento de postfix devuelve el valor del operando antes del incremento.

Del estándar C ++ 17 (8.2.6 Incremento y disminución)

1 El valor de una expresión postfix ++ es el valor de su operando ... El resultado es un prvalue .

Mientras que el operador de incremento unario devuelve lvalue después de su incremento. Entonces esta declaración

int b = (++i)++;

es válido. Podrías por ejemplo escribir

int b = (++++++++i)++;

Del estándar C ++ 17 (8.3.2 Incremento y decremento)

1 El operando del prefijo ++ se modifica agregando 1. El operando será un valor l modificable. El tipo del operando será un tipo aritmético distinto de cv bool, o un puntero a un tipo de objeto completamente definido. El resultado es el operando actualizado; es un valor de l , y es un campo de bits si el operando es un campo de bits ...

Tenga en cuenta que en C los dos operadores devuelven un valor en lugar de lvalue. Entonces en C esta declaración

int b = (++i)++;

no es válido.


i y ++i son ambos valores, pero i++ es un valor r.

++(i++) no puede ser válido, ya que el prefijo ++ se aplica a i++ , que es un valor r. Pero (++i)++ está bien porque ++i es un valor.

Tenga en cuenta que en C, la situación es diferente; i++ y ++i son ambos valores. (Este es un ejemplo de por qué las personas deberían dejar de asumir que C y C ++ tienen las mismas reglas. Las personas insertan estos supuestos en sus preguntas, que luego deben ser refutadas).