Como otros han señalado, el comportamiento es undefined:
6.5 Expresiones
...
2 entre el anterior y el siguiente punto de la secuencia de un objeto tendrá su valor almacenado modificado como máximo una vez por la evaluación de una expresión.
72) Además, el valor anterior se leerá solo para determinar el valor que se almacenará.
73)
...
72) Un indicador de estado de coma flotante no es un objeto y puede configurarse más de una vez dentro de una expresión. 73) Este párrafo renders expresiones de los estados no definidos tales como
i = ++i + 1;
a[i++] = i;
al tiempo que permite
i = i + 1;
a[i] = i;
La expresión i = ++i % 3
intentos de modificar el valor contenido en i
dos veces antes de que el siguiente punto de secuencia (en este caso, el ;
finalizando la declaración), una vez evaluando ++i
, y una vez evaluando la expresión de asignación más grande.
Ahora, ¿por qué sería esto un problema? Después de todo, C# y Java pueden manejar estas expresiones muy bien. El problema es que, con pocas excepciones, C no garantiza que los operandos en una expresión se evalúen en un orden particular, o que los efectos secundarios de una expresión se apliquen inmediatamente después de que se evalúe la expresión (a diferencia de C# y Java, que hacen esas garantías).Por ejemplo, la expresión ++i
tiene un resultado (i
+ 1) y un efecto lado (incrementar el valor almacenado en i
); sin embargo, el efecto secundario puede diferirse hasta que se haya evaluado la expresión más grande. IOW, se permite la siguiente secuencia de acciones:
t0 = i + 1
t1 = t0 % 3
i = t1
i = i + 1
Oopsie. No es lo que queríamos
Esta fue una decisión de diseño deliberada; la idea es que permite a los compiladores reordenar las evaluaciones de manera óptima (por ejemplo, aprovechando un valor que ya está en un registro). La desventaja es que ciertas combinaciones de expresiones tendrán resultados impredecibles.
La * operación * no está definida, no es 'i' en sí misma. Es decir. es un comportamiento indefinido. No lo hagas –
@Paul R ¿por qué crees que la operación no está definida? ++ i aumenta i a 1 y el módulo opeartor 1 con 3 da 1 como resultado. no funciona? – niko
@niko: Vea mi respuesta y http://www.catb.org/jargon/html/N/nasal-demons.html –