Die ordnungsgemäße manuelle logische XOR-Implementierung hängt davon ab, wie genau Sie das allgemeine Verhalten anderer logischer Operatoren ( ||
und &&
) mit Ihrem XOR nachahmen möchten . Diese Operatoren haben zwei wichtige Eigenschaften: 1) Sie garantieren eine Kurzschlussbewertung, 2) sie führen einen Sequenzpunkt ein, 3) sie bewerten ihre Operanden nur einmal.
Wie Sie verstehen, kann die XOR-Auswertung nicht kurzgeschlossen werden, da das Ergebnis immer von beiden Operanden abhängt. 1 kommt also nicht in Frage. Aber was ist mit 2? Wenn Sie sich nicht für 2 interessieren, dann mit normalisiert (dhbool
!=
erledigt der Operator ) Werten die Aufgabe von XOR in Bezug auf das Ergebnis. Und die Operanden können bei Bedarf leicht mit unär normalisiert werden !
. Somit !A != !B
implementiert die richtige XOR in dieser Hinsicht.
Aber wenn Sie sich für den zusätzlichen Sequenzpunkt interessieren, auch nicht !=
noch bitweise ^
der richtige Weg, um XOR zu implementieren. Eine Möglichkeit, XOR (a, b) korrekt auszuführen, könnte wie folgt aussehen
a ? !b : b
Dies ist tatsächlich so nah wie möglich daran, ein hausgemachtes XOR "ähnlich" zu ||
und zu machen &&
. Dies funktioniert natürlich nur, wenn Sie Ihr XOR als Makro implementieren. Eine Funktion funktioniert nicht, da die Sequenzierung nicht auf die Argumente der Funktion angewendet wird.
Jemand könnte jedoch sagen, dass der einzige Grund, an jedem einen Sequenzpunkt zu haben &&
und darin ||
besteht, die kurzgeschlossene Auswertung zu unterstützen, und XOR daher keinen benötigt. Das macht eigentlich Sinn. Es lohnt sich jedoch, ein XOR mit einem Sequenzpunkt in der Mitte in Betracht zu ziehen. Zum Beispiel der folgende Ausdruck
++x > 1 && x < 5
hat das Verhalten und das spezifizierte Ergebnis in C / C ++ definiert (zumindest in Bezug auf die Sequenzierung). Man könnte also vernünftigerweise dasselbe von benutzerdefiniertem logischem XOR erwarten wie in
XOR(++x > 1, x < 5)
Ein !=
XOR auf Basis hat diese Eigenschaft nicht.