L' implémentation manuelle XOR logique appropriée dépend de la façon dont vous souhaitez imiter le comportement général des autres opérateurs logiques ( ||
et &&
) avec votre XOR. Il y a deux choses importantes à propos de ces opérateurs: 1) ils garantissent l'évaluation des courts-circuits, 2) ils introduisent un point de séquence, 3) ils évaluent leurs opérandes une seule fois.
L'évaluation XOR, comme vous le comprenez, ne peut pas être court-circuitée car le résultat dépend toujours des deux opérandes. Donc 1 est hors de question. Mais qu'en est-il de 2? Si vous ne vous souciez pas de 2, alors avec des bool
valeurs normalisées (c'est-à-dire ), l'opérateur !=
fait le travail de XOR en termes de résultat. Et les opérandes peuvent être facilement normalisés avec unaire !
, si nécessaire. Implémente ainsi !A != !B
le XOR approprié à cet égard.
Mais si vous vous souciez du point de séquence supplémentaire, !=
ni le bit ni le bit ^
n'est la bonne façon d'implémenter XOR. Une façon possible de faire XOR (a, b) correctement pourrait se présenter comme suit
a ? !b : b
Ceci est en fait aussi proche que possible de la fabrication d'un XOR maison "similaire" à ||
et &&
. Cela ne fonctionnera, bien sûr, que si vous implémentez votre XOR en tant que macro. Une fonction ne fonctionnera pas, car le séquencement ne s'appliquera pas aux arguments de la fonction.
Quelqu'un pourrait dire cependant que la seule raison d'avoir un point de séquence à chacun &&
et ||
est de prendre en charge l'évaluation en court-circuit, et donc XOR n'en a pas besoin. Cela a du sens, en fait. Pourtant, il vaut la peine d'envisager d'avoir un XOR avec un point de séquence au milieu. Par exemple, l'expression suivante
++x > 1 && x < 5
a un comportement défini et un résultat spécifique en C / C ++ (en ce qui concerne le séquençage au moins). Donc, on peut raisonnablement s’attendre à la même chose de la part du XOR logique défini par l’utilisateur , comme dans
XOR(++x > 1, x < 5)
tandis qu'un !=
XOR basé sur n'a pas cette propriété.