L'ordine di valutazione delle ^=
operatori è ben definito. Ciò che non è ben definito è l'ordine in cui vengono modificati a
e b
.
a ^= b ^= a ^= b;
è equivalente a
a ^= (b ^= (a ^= b));
L'operatore non può essere valutata prima suoi argomenti vengono valutati, quindi è sicuramente andando ad eseguire a ^= b
prima.
Il motivo per cui questo comportamento è indefinito è che, per dare al compilatore maggiore flessibilità nelle ottimizzazioni, è consentito modificare i valori delle variabili in qualsiasi ordine esso scelga.Si potrebbe scegliere di fare questo:
int a1 = a^b;
int b1 = b^a1;
int a2 = a^b1;
a = a1;
a = a2;
b = b1;
o questo:
int a1 = a^b;
int b1 = b^a1;
a = a1;
int a2 = a^b1;
a = a2;
b = b1;
o anche questo:
int a1 = a^b;
int b1 = b^a1;
int a2 = a^b1;
a = a2;
a = a1;
b = b1;
Se il compilatore potrebbe scegliere solo uno di questi tre modi di fare le cose, questo sarebbe solo un comportamento "non specificato". Tuttavia, lo standard va oltre e rende questo comportamento "indefinito", che sostanzialmente consente al compilatore di presumere che non può nemmeno accadere.
fonte
2013-07-04 17:05:24
Se scrivi un codice che è difficile dire cosa sta succedendo, chiediti se esiste un modo più semplice che un futuro sviluppatore possa capire? –
Si noti che se si è visto questo in codice C++, C++ ha regole diverse per gli operatori di assegnazione che consentono determinati costrutti (non sono sicuro di questo) che non sono definiti in C. – hvd
possibile duplicato di [Punto sequenza - Xor Swap on Array ottiene risultati errati] (http://stackoverflow.com/questions/9958514/sequence-point-xor-swap-on-array-get-wrong-result) –