Tengo el siguiente código:
#include <stdio.h>
int main(int argc, char **argv) {
int i = 0;
(i+=10)+=10;
printf("i = %d\n", i);
return 0;
}
Si intento compilarlo como fuente C usando gcc, aparece un error:
error: lvalue required as left operand of assignment
Pero si lo compilo como una fuente de C ++ usando g ++ no obtengo ningún error y cuando ejecuto el ejecutable:
i = 20
¿Por qué el comportamiento diferente?
Respuestas:
La semántica de los operadores de asignación compuesta es diferente en C y C ++:
Estándar C99, 6.5.16, parte 3:
En C ++ 5.17.1:
EDITAR: El comportamiento de
(i+=10)+=10
en C ++ no está definido en C ++ 98, pero está bien definido en C ++ 11. Consulte esta respuesta a la pregunta de NPE para conocer las partes relevantes de los estándares.fuente
(i+=10)+=10
tenga en cuenta que es un comportamiento indefinido en C ++, consulte la respuesta de @aix.int f(int &y); f(x += 10);
: pasar una referencia a la variable modificada a una función.Además de ser un código C inválido, la línea
daría como resultado un comportamiento indefinido tanto en C como en C ++ 03 porque se modificaría
i
dos veces entre los puntos de secuencia.En cuanto a por qué está permitido compilar en C ++:
El mismo párrafo continúa diciendo que
Esto sugiere que en C ++ 11, la expresión ya no tiene un comportamiento indefinido.
fuente
i
que no están secuenciadas.i = j+=1
, el resultado sería un valor indeterminado. En el mismo párrafo, cita "En todos los casos, la asignación se secuencia después del cálculo del valor de los operandos derecho e izquierdo, y antes del cálculo del valor de la expresión de asignación". Por(i+=10)+=10
lo tanto, está bien definido para haceri += 10; i += 10;
. Por otro lado(i+=10)+=(i+=10)
está UB.