Nel linguaggio C, le operazioni di incremento postfisso (i++) e prefisso (++i) aumentano il valore di una variabile di 1, ma il valore restituito è diverso:
Esempio:
int i = 5; int a = i++; // a == 5, i == 6 int j = 5; int b = ++j; // b == 6, j == 6
In espressioni semplici, la differenza non è significativa, ma in espressioni complesse (ad esempio, con più incrementi contemporaneamente) può sorgere un comportamento indefinito.
Quale sarà il valore della variabile a dopo l'esecuzione dell'espressione
int a = i++ + ++i;, sei = 1?
Il risultato dipende dall'ordine di valutazione degli operandi, che non è garantito dallo standard, e porta a un comportamento indefinito (undefined behavior), poiché la variabile i viene modificata più di una volta tra l'uso sequenziale del valore. Non è corretto scrivere in questo modo!
Esempio di tale codice:
int i = 1; int a = i++ + ++i; // comportamento indefinito! Non usare in questo modo!
Storia
In un grande progetto, il calcolo dell'indice in un array era scritto come arr[i++] = getValue(++i); — lo sviluppatore voleva mantenere il vecchio valore, mentre otteneva il nuovo. Su diversi compilatori, il comportamento variava: a volte un valore sovrascriveva l'altro, altre volte il programma si bloccava. La causa era dovuta a modifiche multiple non valide di i in un'unica espressione.
Storia
In un progetto embedded, il valore di un contatore veniva incrementato come parte di un'espressione complessa: if (buffer[i++] == TERMINATOR && ++i < SIZE) ... — su “hardware” talvolta si otteneva un indice errato a causa del diverso ordine di valutazione, portando alla lettura di dati non inizializzati.
Storia
Durante il porting del codice su un altro compilatore, la differenza nell'implementazione dell'ordine di valutazione degli operandi portò a situazioni in cui un ciclo del tipo while (arr[i++] && i < MAX && arr[++i]) iniziava a comportarsi in modo imprevedibile. Il bug è stato scoperto solo a seguito della fase di testing già su un dispositivo del cliente.