Non è definito perché si modifica x
due volte tra i punti della sequenza. Lo standard dice che non è definito, quindi non è definito.
Questo lo so.
Ma perché?
La mia comprensione è che proibire questo consente ai compilatori di ottimizzare meglio. Questo avrebbe potuto avere senso quando fu inventata la C, ma ora sembra un argomento debole.
Se dovessimo reinventare la C oggi, lo faremmo in questo modo o potrebbe essere fatto meglio?
O forse c'è un problema più profondo, che rende difficile definire regole coerenti per tali espressioni, quindi è meglio vietarle?
Quindi supponiamo che dovremmo reinventare C oggi. Vorrei suggerire semplici regole per espressioni come x=x++
, che mi sembrano funzionare meglio delle regole esistenti.
Mi piacerebbe avere la tua opinione sulle regole suggerite rispetto a quelle esistenti o altri suggerimenti.
Regole suggerite:
- Tra i punti di sequenza, l'ordine di valutazione non è specificato.
- Gli effetti collaterali si verificano immediatamente.
Non ci sono comportamenti indefiniti coinvolti. Le espressioni valutano questo valore o quello, ma sicuramente non formatteranno il tuo disco rigido (stranamente, non ho mai visto un'implementazione in cui x=x++
formatta il disco rigido).
Espressioni di esempio
x=x++
- Ben definito, non cambiax
.
Innanzitutto,x
viene incrementato (immediatamente quandox++
viene valutato), quindi viene archiviato il valore precedentex
.x++ + ++x
- Incrementax
due volte, valuta2*x+2
.
Sebbene una delle parti possa essere valutata per prima, il risultato èx + (x+2)
(prima la parte sinistra) o(x+1) + (x+1)
(prima la parte destra).x = x + (x=3)
- Non specificato,x
impostato sux+3
o6
.
Se il lato destro viene valutato per primo, lo èx+3
. È anche possibile chex=3
venga valutato per primo, quindi lo è3+3
. In entrambi i casi, l'x=3
assegnazione avviene immediatamente quandox=3
viene valutata, quindi il valore memorizzato viene sovrascritto dall'altra assegnazione.x+=(x=3)
- Ben definito, impostatox
su 6.
Si potrebbe sostenere che questa è solo una scorciatoia per l'espressione sopra.
Ma direi che+=
deve essere eseguito dopox=3
, e non in due parti (leggix
, valutax=3
, aggiungi e memorizza un nuovo valore).
Qual è il vantaggio?
Alcuni commenti hanno sollevato questo buon punto.
Certamente non penso che espressioni come quelle x=x++
dovrebbero essere usate in nessun codice normale.
In realtà, sono molto più severo di quello - penso che l'unico buon uso sia x++
da x++;
solo.
Tuttavia, penso che le regole del linguaggio debbano essere il più semplice possibile. Altrimenti i programmatori non li capiscono. la regola che vieta di cambiare due volte una variabile tra punti di sequenza è certamente una regola che la maggior parte dei programmatori non capisce.
Una regola molto semplice è questa:
se A è valido e B è valido e sono combinati in modo valido, il risultato è valido.
x
è un valore L valido, x++
è un'espressione valida ed =
è un modo valido per combinare un valore L e un'espressione, quindi come x=x++
mai non è legale?
Lo standard C fa un'eccezione qui, e questa eccezione complica le regole. Puoi cercare stackoverflow.com e vedere quanto questa eccezione confonde le persone.
Quindi dico: liberati di questa confusione.
=== Riepilogo delle risposte ===
Perché farlo?
Ho cercato di spiegare nella sezione sopra - Voglio che le regole C siano semplici.Potenziale di ottimizzazione:
questo libera un po 'di libertà dal compilatore, ma non ho visto nulla che mi abbia convinto che potrebbe essere significativo.
La maggior parte delle ottimizzazioni può ancora essere eseguita. Ad esempio,a=3;b=5;
può essere riordinato, anche se lo standard specifica l'ordine. Espressioni come quellea=b[i++]
possono ancora essere ottimizzate in modo simile.Non è possibile modificare lo standard esistente.
Lo ammetto, non posso. Non avrei mai pensato di poter davvero andare avanti e cambiare standard e compilatori. Volevo solo pensare se le cose avrebbero potuto essere fatte diversamente.
x
a se stesso, e se vuoi incrementarex
puoi semplicemente direx++;
- non è necessario per il compito. Direi che non dovrebbe essere definito solo perché sarebbe difficile ricordare cosa dovrebbe succedere.