En el lenguaje C, las operaciones de incremento postfijo (i++) y prefijo (++i) aumentan el valor de la variable en 1, pero el valor devuelto es diferente:
Ejemplo:
int i = 5; int a = i++; // a == 5, i == 6 int j = 5; int b = ++j; // b == 6, j == 6
En expresiones simples, la diferencia no es significativa, pero en expresiones complejas (por ejemplo, con varios incrementos a la vez) puede surgir un comportamiento indefinido.
¿Cuál será el valor de la variable a después de ejecutar la expresión
int a = i++ + ++i;, sii = 1?
El cálculo depende del orden de evaluación de los operandos, el cual no está garantizado por el estándar, y también conduce a un comportamiento indefinido, porque la variable i se modifica más de una vez entre el uso secuencial de su valor. ¡No se debe escribir así!
Ejemplo de tal código:
int i = 1; int a = i++ + ++i; // ¡comportamiento indefinido! ¡No lo use así!
Historia
En un gran proyecto, el cálculo del índice en un arreglo se escribía como arr[i++] = getValue(++i); — el desarrollador quería conservar el valor antiguo mientras obtenía uno nuevo. En diferentes compiladores, el comportamiento variaba: a veces un valor sobrescribía al otro, a veces el programa fallaba. La razón — modificaciones múltiples no permitidas de i en una sola expresión.
Historia
En un proyecto embebido, el valor del contador se incrementaba como parte de una expresión compleja: if (buffer[i++] == TERMINATOR && ++i < SIZE) ... — en «hardware» a veces se obtenía un índice incorrecto debido al diferente orden de evaluación, lo que llevaba a la lectura de datos no inicializados.
Historia
Al portar código a otro compilador, la diferencia en la implementación del orden de evaluación de los operandos provocó que un bucle como while (arr[i++] && i < MAX && arr[++i]) comenzara a comportarse de manera impredecible. El error se encontró solo a partir de los resultados de la fase de prueba ya en el dispositivo del cliente.