Ordine di valutazione di assegnazione (ho trovato il mio primo bug del compilatore?)
-
24-09-2019 - |
Domanda
Questo codice ha un interessante bug:
some_struct struct_array1[10] = {0};
some_struct struct_array2[10] = {0}
int i;
for (i = 0;
i < sizeof(struct_array1) / sizeof(struct_array1[0]);
struct_array1[i].value = struct_array2[i++].value = 1)
;
Per la maggior parte dei compilatori, i risultati di cui sopra nel codice impostando il campo "valore" di tutte le strutture nelle rispettive matrici per 1. Tuttavia, per un compilatore specifico (chiamiamolo XCC), le struct in struct_array1 non sono inizializzati correttamente. Il campo "Valore" è impostato su 0 per tutte le strutture, che tipo di mi ha sorpreso.
Le seguenti opere frammento di codice come previsto su tutti i compilatori:
for (i = 0;
i < sizeof(struct_array1) / sizeof(struct_array1[0]);
i++)
{
struct_array1[i].value = struct_array2[i].value = 1;
}
Ora, io sono completamente fuori qui, o fa il compilatore incriminata "XCC" semplicemente visualizzo un bug?
Non riesco a trovare nulla che il comportamento display implementazione specifico nel primo frammento di codice; Da quanto ho capito l'Incremento postfix dovrebbe avere la precedenza sulle assegnazioni e le assegnazioni dovrebbero essere valutati da destra a sinistra. Non ci dovrebbe essere nulla di strano con il primo frammento di codice, tranne che è un po 'illeggibile.
Soluzione
Hai invocato comportamento indefinito, perché modifica i
e recupera il suo valore per uno scopo diverso calcolare il nuovo valore, senza punto sequenza parimenti intervenuto.
La parte rilevante dello standard C99 è questa clausola nella sezione 6.5:
Tra la sequenza precedente e successivo puntare un oggetto deve avere la sua memorizzata valore modificato al massimo una volta dal valutazione di un'espressione. Inoltre, il valore precedente è sola lettura per determinare il valore di essere memorizzato.
Altri suggerimenti
struct_array1[i].value = struct_array2[i++].value = 1
Penso che sia un comportamento indefinito perché i++
non è garantito per completare tutti i suoi effetti collaterali fino al raggiungimento del successivo punto di sequenza. Il prossimo punto di sequenza è la ;
'immaginario' alla fine dell'istruzione. Questo è un errore comune, penso che si possono trovare molti argomenti su SO pertinenza di esso, basta cercare i punti di sequenza.
In realtà non siamo supponiamo di eseguire più di una valutazione per stessa variabile, in signle
espressione. Se facciamo quella cosa, sarà un comportamento indefinito.