85 votes

Utilisation d'opérateurs au niveau du bit pour les booléens en C ++

Est-il une raison de ne pas utiliser le bit à bit les opérateurs &, | et ^ pour "bool" valeurs en C++?

J'ai parfois l'exécuter dans des situations où je veux exactement l'une des deux conditions pour être vrai (XOR), donc je viens de lancer le ^ opérateur dans une expression conditionnelle. J'ai aussi parfois besoin de toutes les pièces d'une condition à évaluer si le résultat est vrai ou pas (plutôt que de court-circuit), donc j'utilise & et |. J'ai aussi besoin d'accumuler des valeurs Booléennes parfois, et &= et |= peut être très utile.

J'ai eu quelques soulevé les sourcils quand le faire, mais le code est toujours significatif et plus propre qu'il en serait autrement. Est-il une raison de ne PAS les utiliser pour booléens? Sont là tout les compilateurs modernes qui donnent de mauvais résultats?

62voto

Patrick Points 20392

|| et && sont des opérateurs booléens et sont garantis pour revenir 1 ou 0. Rien d'autre.

|, & et ^ sont des opérateurs au niveau du bit. Lorsque le domaine de numéros de fonctionnement sur est que de 1 et de 0, alors qu'ils sont exactement les mêmes, mais dans les cas où votre booléens ne sont pas strictement des 1 et des 0--comme c'est le cas avec le langage c--vous pouvez vous retrouver avec un comportement que vous ne vouliez pas. Par exemple:

BOOL two = 2;
BOOL one = 1;
BOOL and = two & one;   //and = 0
BOOL cand = two && one; //cand = 1

En c++, cependant, le type bool est garanti d'être seulement un 1 ou un 0, il est donc moins de souci à partir de cette position, mais le fait que les gens ne sont pas habitués à voir de telles choses dans le code qui fait un bon argument pour ne pas le faire. Juste dire b = b && x et être fait avec elle.

33voto

Patrick Johnmeyer Points 5947

Deux raisons principales. En bref, l'examiner attentivement; il pourrait y avoir une bonne raison pour cela, mais si il est TRÈS explicite dans vos commentaires, car il peut être fragile et, comme vous le dites vous-même, les gens ne sont généralement pas l'habitude de voir ce type de code.

Xor au niveau du bit != Logique xor (à l'exception de 0 et de 1)

Tout d'abord, si vous êtes d'exploitation sur d'autres valeurs que false et true (ou 0 et 1, comme les entiers), l' ^ opérateur peut introduire comportement n'équivaut pas à une logique xor. Par exemple:

int one = 1;
int two = 2;

// bitwise xor
if (one ^ two)
{
  // executes because expression = 3 and any non-zero integer evaluates to true
}

// logical xor; more correctly would be coded as
//   if (bool(one) != bool(two))
// but spelled out to be explicit in the context of the problem
if ((one && !two) || (!one && two))
{
  // does not execute b/c expression = ((true && false) || (false && true))
  // which evaluates to false
}

De crédit de l'utilisateur @Patrick pour exprimer cette première.

Ordre des opérations

Deuxièmement, |, &, et ^, que les opérateurs au niveau du bit, ne pas faire de court-circuit. En outre, plusieurs opérateurs au niveau du bit enchaînés dans un seul énoncé, même avec des parenthèses explicites, peuvent être réorganisées par l'optimisation des compilateurs, parce que tous les 3 opérations sont normalement commutative. Ceci est important si l'ordre des opérations de questions.

En d'autres termes

bool result = true;
result = result && a() && b();
// will not call a() if result false, will not call b() if result or a() false

ne sera pas toujours donner le même résultat (ou à la fin de l'état)

bool result = true;
result &= (a() & b());
// a() and b() both will be called, but not necessarily in that order in an
// optimizing compiler

Ceci est particulièrement important parce que vous ne pouvez pas les méthodes de contrôle a() et b(), ou quelqu'un d'autre peut venir le long et les modifier par la suite de ne pas comprendre la dépendance, et de provoquer un méchant (et souvent de presse-construire uniquement) bug.

13voto

Mark Borgerding Points 2259

je pense

 a != b
 

c'est ce que tu veux

11voto

kokos Points 10083

Les sourcils levés devraient vous en dire assez pour arrêter de le faire. Vous n'écrivez pas le code pour le compilateur, vous l'écrivez d'abord pour vos collègues programmeurs, puis pour le compilateur. Même si les compilateurs fonctionnent, surprendre d’autres personnes n’est pas ce que vous voulez - les opérateurs au niveau du bit s’appliquent aux opérations de bits, pas à les bools.
Je suppose que vous mangez aussi des pommes avec une fourchette? Ça marche mais ça surprend les gens, alors mieux vaut ne pas le faire.

3voto

bk1e Points 13737

Contrairement à Patrick de réponse, C++ n'a pas d' ^^ de l'opérateur pour la réalisation d'un court-circuit ou exclusif. Si vous pensez à ce sujet pendant une seconde, d'avoir un ^^ opérateur n'aurait pas de sens de toute façon: avec ou exclusif, le résultat dépend toujours de deux opérandes. Cependant, Patrick avertissement au sujet de la non-bool "Boolean" types détient aussi bien lorsque l'on compare 1 & 2 de 1 && 2. Un exemple classique est le Windows GetMessage() la fonction, qui renvoie à un tri de l'état- BOOL: non nulle, 0ou -1.

À l'aide de & au lieu de && et | au lieu de || n'est pas rare qu'une faute de frappe, donc si vous êtes délibérément de le faire, il mérite un commentaire en expliquant pourquoi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X