7
votes

Deux booléens peuvent-ils être comparés en C ++?

est le code de code suivant censé fonctionner? XXX

Je soupçonne que toutes les "traditions" ne sont pas égales.


8 commentaires

Vous impliquez que vous avez testé ce code et la partie "// faire quelque chose" n'a pas été exécuté?


Quelle devrait être la différence entre vrai et vrai être?


Oui, bien sûr :-) Mon scénario était plutôt plus compliqué mais en principe oui. (Peut-être que j'ai fait quelque chose d'autre mal mais la réécriture == a résolu mon problème).


@svegi: Je soupçonnai que le vrai n'est que tout autreo (peut-être une optimisation du compilateur?). Comme dans C.


@Danatel: si vous convertissez true à un entier, il est 1 . Si vous convertissez un entier en Boolean, toute valeur autre que zéro est true .


@Danatel alors la différence a été causée par la partie "plutôt plus compliquée", non par la version simplifiée que vous avez postée.


True == static_cast (2) mais vrai! = 2. Peut-être que c'était la différence.


Dans mon code, il n'y avait pas de moulage. Un booléen était de la variable booléenne, l'autre d'appeler la fonction booléenne en ligne qui contenait un bitwise et comme ceci: Bool Test () {retour (x & 2)! = 0; }. Je fais donc une erreur vraiment stupide que je n'ai pas vue ou que le compilateur a fait une optimisation étrange. Le premier est beaucoup plus probable :-).


8 Réponses :


19
votes

Oui. Toutes les traditions sont égales.


8 commentaires

Eh bien, ils sont égaux aussi loin que == est concerné. Sauf si le programmeur ait fait quelque chose comme le remplacement opérateur == pour toujours retourner false . Puisque rien dans la question n'est un objet, ce ne sera pas le cas.


@Mike D. Même si nous avions des objets, opérateur remplissant == afin qu'il retourne toujours faux ne semble pas une technique très intuitive pour moi.


Je vais élever la barre sur cette réponse: toutes les fales sont également fausses.


@nobugz En fait, vous avez abaissé la barre. Parce que les falmes ont été toujours égales, même en C.


@nobugz La règle complète serait la suivante: "Toutes les traditions sont égales. Toutes les failles sont égales. Toutes les tâches sont également vraies. Toutes les failles sont également fausses. Enfin, vrai est différent de faux."


@Danatel: Je ne suis pas d'accord. Il a soulevé la barre dans la mesure où il a ajouté des informations à ma réponse. C est une langue différente.


@Danatel: Je ne pense pas (vide *) 0 , 0 et 0.0 sont tous égaux, mais ils sont tous faux dans C.


@Daniel: Je sais que, mais j'ai vu suffisamment d'abus de surcharge de l'opérateur que je peux apprécier (tout d'accord avec) ceux qui préfèrent interdire la surcharge de l'opérateur. Personnellement, j'utilise beaucoup le modèle complexe , alors je préférerais le garder.



1
votes

in c avec int s Vous pourriez avoir un point (bien que même là, je pense que cette séquence particulière serait OK). En C ++, oui c'est sûr.


0 commentaires

8
votes

Oui, comme d'autres ont dit que les bools peuvent être comparés à l'égalité en C ++. Vous pensez peut-être des choses que vous avez entendues de C. Depuis C n'a pas de type Bool, les booléens sont représentés comme des entiers. Dans un contexte booléen, tout entier non nul n'est vrai. Cependant, ils pourraient avoir des modèles de bits différents et donc ne pas être égaux. Donc, la règle en C n'était pas de comparer des «booléens».

Edit: par commentaires, C99 a un type bool. Cependant, le point de la réponse était d'indiquer pourquoi l'idée de ne pas comparer que les bools est flottant autour. Il est basé sur la longue histoire de C, avant C99.



10
votes

Oui, les valeurs booléennes ne peuvent stocker que true ou false, et vous pouvez comparer les valeurs d'égalité.

Cependant, certains mauvaises utilisations forte> de variables BOOL peuvent conduire à des comportements "indéfinis" et pourraient Regardez comme si ce n'est ni vrai ni faux. Par exemple, la lecture de la valeur d'une variable automatique non initialisée ou d'une copie de mémoire directe à partir d'entiers. P>

examine l'exemple suivant (mauvais) Exemple: P>

  bool b1 = true; 
  bool b2 = true; 
  *((char*)&b1) = 3;

  if( b1 ) cout << "b1 is true" << endl;
  if( b2 ) cout << "b2 is true" << endl;
  if (b1 != b2) cout << "b2 is not equal to b1" << endl;


5 commentaires

Je ne peux pas imaginer que quelqu'un contortait la langue de la manière dont vous avez en ligne 3. C'est une déclaration bizarre. Pas que votre point soit moins valable ...


Techniquement, le comportement non défini provient de mauvaise utilisation d'une fonte, non de booléen.


@ERIC: Oui, je suis d'accord que la ligne 3 n'est pas "Code réel". C'était un court exemple pour démontrer que la phrase: «Tous les« trues »sont égales» peuvent être vraies.


Structures mappées en mémoire. Jolie commune dans la programmation C / C ++.


Techniquement, si quelqu'un avait contorqué la valeur booléenne en tant que telle à la ligne 3, ils devraient être capables de le réparer facilement en faisant: B1 = !! B1; b2 = !! b2;



0
votes

Les problèmes ne sont que lorsque vous vous habituez à ne pas être vrais et d'oublier que tous les non-zéros ne sont pas égaux.

Imaginez ceci: p>

Vous avez une fonction claviche () qui retourne 0 sur NO TEULE enfoncée, Numéro de clé lorsqu'une touche est enfoncée. P>

Vous avez écrit un commutateur simple dans une boucle: P>

if((keyPressed() == key_switches_on) && allow)


0 commentaires

2
votes

Lorsque vous attribuez une valeur intégrale à un objet booléen (ou initialisez l'objet booléen à une valeur intégrale), il est implicitement converti en un true ou false par un booléen standard conversion (4.12). Donc, du point de vue linguistique, votre 1 et 2 est parti sans trace long avant même de faire la comparaison. Ils sont tous deux devenus le même vrai . Il n'y a pas de "toutes les trues sont égales" problème ici. Il n'y a qu'un seul vrai .

Bien sûr, un compilateur pourrait probablement adopter une approche "paresseuse" et garder plusieurs "traditions" différentes autour, en veillant à ce qu'ils "tous sont égaux" au moment de comparaison et tels, mais je doute qu'il s'agisse d'une approche raisonnable / viable.

En d'autres termes, dans une mise en œuvre raisonnable, vous devriez vous attendre non seulement à votre comparaison pour tenir vrai, mais une comparaison beaucoup plus forte à être vraie Eh bien: xxx

Ceci n'est pas garanti par la langue, mais dans la vie réelle, il décrit très bien le côté physique de la situation.


0 commentaires

1
votes

in c ++, bool est son propre type, avec les deux valeurs possibles true et false . Toutes les comparaisons iront comme vous vous attendez. Tous les true Les valeurs booléennes sont la même chose, et la même chose avec tous les faux . Il est vrai que toutes les expressions qui ne peuvent pas être évaluées à true ou false sont les mêmes.

en C89, pour remonter aussi loin que je veux, toute valeur zéro (de tout pointeur ou type numérique) est fausse et tout ce qui est vrai. Cela signifie que les vraies valeurs ne sont pas nécessairement égales entre elles. 1 et 2 sont des valeurs réelles, mais 1! = 2 et 1 et 2 évalue à 0, qui est faux.

Il est également possible pour C89 fausses valeurs de ne pas comparer égale, bien qu'ils soient sur chaque mise en œuvre que j'ai jamais utilisée. Une valeur de pointeur NULL est une mise à zéro intégrale constante à une valeur de pointeur. Il est possible pour une valeur non constante 0 Cast à une valeur de pointeur pour ne pas être un pointeur NULL (et il y a eu des systèmes dans lesquels des pointeurs NULL n'étaient pas tous les bits 0). Par conséquent, (void *) 0 est une valeur de pointeur NULL, et donc false, mais int i; ... i = 0; ... (vide *) i pourrait éventuellement ne pas être une valeur de pointeur nulle, et donc pas fausse.

Cependant, dans C89, toutes les opérations qui ont l'intention de renvoyer une valeur booléenne (comme && ou == , par exemple), retourneront 1 ou 0, de sorte que (1 == 3) == (4 == 3) .


0 commentaires

0
votes

J'ai lu toutes ces réponses sur la raison pour laquelle True est vrai et pourquoi deux variables booléennes peuvent être comparées à l'aide de == ou ! = sauf dans des cas rares où Un entier est contraint d'être un bool ou une chose. Cependant, j'ai exactement le même problème que l'affiche originale. J'ai deux variables booléennes, chacune d'entre elles est "vraie", mais quand je les comparais, je trouve qu'ils ne sont pas égaux. Voici la ligne de code,

si (angdegdiff> 15 || Scaleratioa> 5 || Scaleratiob <-5 || (isparallel2! = isparallel1)) { retourner faux; }

Dans mon exemple, angdegdiff = 0 , scalératioa = 0 , scalératiob = 0 , isparallel2 = true , et isparallel1 = true . Néanmoins, la déclaration évalue à true et le seul moyen pour que cela se produise est si isparallel2 n'est pas égal à isparallel1 . .

Aucune méthode de fantaisie n'est utilisée pour définir les valeurs de iSparallel1 ou isparallel2 . Leurs valeurs sont définies par une instruction telle que _isparallel = true; . Plus tard, cette valeur est copiée à une autre variable à l'aide d'une instruction telle que isparallel1 = geom1-> isparallel (); qui est implémenté comme retour _isparallel; . .

Ma conclusion est que, selon le compilateur, deux variables booléennes ne peuvent pas être comparées de manière fiable pour l'égalité. J'utilise Microsoft Visual C ++ 2005, version 8.0.50727.4039.

EPILOGUE: J'ai remplacé la comparaison booléenne dans mon code avec l'expression, ((isparallel1 &&! isparallel2) || (! isparallel1 && isparall2)) et maintenant tout fonctionne bien.


0 commentaires