Die Reihenfolge der Auswertung der ^=
Betreiber ist gut definiert. Was nicht genau definiert ist, ist die Reihenfolge, in der a
und b
modifiziert werden.
a ^= b ^= a ^= b;
entspricht
a ^= (b ^= (a ^= b));
Ein Bediener kann nicht ausgewertet werden, bevor ihre Argumente ausgewertet werden, so ist es auf jeden Fall a ^= b
zuerst gehen auszuführen.
Der Grund für dieses undefinierte Verhalten liegt darin, dass es dem Compiler erlaubt ist, die Flexibilität in Optimierungen zu ändern, und die Variablenwerte in beliebiger Reihenfolge ändern können.Es könnte wählen, dies zu tun:
int a1 = a^b;
int b1 = b^a1;
int a2 = a^b1;
a = a1;
a = a2;
b = b1;
oder dies:
int a1 = a^b;
int b1 = b^a1;
a = a1;
int a2 = a^b1;
a = a2;
b = b1;
oder auch diese:
int a1 = a^b;
int b1 = b^a1;
int a2 = a^b1;
a = a2;
a = a1;
b = b1;
Wenn der Compiler nur eine dieser drei Möglichkeiten wählen, könnten die Dinge zu tun, das wäre nur "unspezifiziertes" Verhalten. Der Standard geht jedoch weiter und macht dies zu einem "undefinierten" Verhalten, was es dem Compiler grundsätzlich erlaubt, anzunehmen, dass es nicht einmal passieren kann.
Wenn Sie Code schreiben, der schwer zu sagen ist, was vor sich geht, fragen Sie sich, ob es einen einfacheren Weg gibt, den ein zukünftiger Entwickler verstehen könnte? –
Beachten Sie, dass, wenn Sie dies in C++ - Code gesehen haben, C++ verschiedene Regeln für die Zuweisungsoperatoren hat, die bestimmte Konstrukte zulassen (ich bin mir nicht sicher), die in C. nicht möglich sind. – hvd
mögliches Duplikat von [Sequenzpunkt - Xor Swap on Array bekomme ein falsches Ergebnis] (http://stackoverflow.com/questions/9958514/sequence-point-xor-swap-on-array-get-wrong-result) –