137 votes

Pourquoi c ++ n'a-t-il pas && = ou || = pour les booléens?

Y a-t-il une "très mauvaise chose" qui peut arriver && = et || = ont été utilisés comme sucre syntaxique pour bool foo = foo && bar et bool foo = foo || bar ?

82voto

Konrad Rudolph Points 231505

Un bool ne peuvent être true ou false en C++. En tant que tel, à l'aide de &= et |= est parfaitement sûr (même si je n'aime pas particulièrement la notation). Vrai, ils vont effectuer des opérations sur les bits plutôt que des opérations logiques (et en tant que tel, ils ne seront pas court-circuit), mais ces opérations sur les bits de suivre un plan bien défini de cartographie, qui est en fait l'équivalent de la logique des opérations, aussi longtemps que les deux opérandes sont en effet de type bool.

Contrairement à ce que d'autres personnes l'ont dit ici, un bool en C++ ne doit jamais avoir une valeur différente, par exemple 2. Lors de l'affectation d'une valeur à un bool, elle sera convertie en true , conformément à la norme.

La seule façon d'obtenir une valeur non valide dans un bool est par l'utilisation de reinterpret_cast sur les pointeurs:

int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn't on my PC!)

Mais à partir de ce code entraîne un comportement indéterminé de toute façon, on peut ignorer ce problème potentiel dans le respect du code C++.

47voto

nikie Points 7479

&& et & ont des sémantiques différentes: && n'évaluera pas le deuxième opérande si le premier opérande est - false. c'est à dire quelque chose comme

flag = (ptr != NULL) && (ptr->member > 3);

est sûr, mais

flag = (ptr != NULL) & (ptr->member > 3);

n'est pas, même si les deux opérandes sont de type bool.

Le même est vrai pour &= et |=:

flag = CheckFileExists();
flag = flag && CheckFileReadable();
flag = flag && CheckFileContents();

va se comporter différemment que:

flag = CheckFileExists();
flag &= CheckFileReadable();
flag &= CheckFileContents();

29voto

olibre Points 6069

Raison

Les opérateurs &&= et ||= ne sont pas disponibles sur le C / C++ / Java parce que :

  • le risque d'erreur de
  • inutile

Exemple pour &&=

Si C ou C++ ou Java autorisés &&= de l'opérateur, ce code:

bool ok = true; //becomes false when at least a function returns false
ok &&= f1();
ok &&= f2(); //we may expect f2() is called whatever the f1() returned value

est équivalent à:

bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true

Ce premier code est le risque d'erreur de parce que de nombreux développeurs penserait f2() est toujours appelé quelle que soit l' f1() la valeur retournée. C'est comme l'écriture d' bool ok = f1() && f2();f2() n'est appelé que lorsque f1() retours true.

  • Si le développeur veut réellement f2() seulement lors de l' f1() retours true, donc le deuxième code ci-dessus est moins sujette aux erreurs.
  • Autre personne (le développeur veut f2() toujours être appelé), &= suffit:

Exemple pour &=

bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value

En outre, il est plus facile pour le compilateur d'optimiser ce code ci-dessus que celle ci-dessous:

bool ok = true;
if (!f1())  ok = false;
if (!f2())  ok = false;  //f2() always called

Comparer && et &

On peut se demander si les opérateurs && et & donnent le même résultat lorsqu'il est appliqué sur bool valeurs?

Nous allons vérifier en utilisant le code C++ suivant:

#include <iostream>

void test (int testnumber, bool a, bool b)
{
   std::cout << testnumber <<") a="<< a <<" and b="<< b <<"\n"
                "a && b = "<< (a && b)  <<"\n"
                "a &  b = "<< (a &  b)  <<"\n"
                "======================"  "\n";
}

int main ()
{
    test (1, true,  true);
    test (2, true,  false);
    test (3, false, false);
    test (4, false, true);
}

Sortie:

1) a=1 and b=1
a && b = 1
a &  b = 1
======================
2) a=1 and b=0
a && b = 0
a &  b = 0
======================
3) a=0 and b=0
a && b = 0
a &  b = 0
======================
4) a=0 and b=1
a && b = 0
a &  b = 0
======================

Conclusion

Donc OUI on peut remplacer && par & pour bool valeurs ;-)
Afin de mieux utiliser &= au lieu de &&=.
On peut considérer &&= comme inutile pour les booléens.

De même pour ||=

opérateur de |= est également moins sujettes à l'erreur qu' ||=

Si un développeur veut f2() seulement être appelée lors de l' f1() retours false, au lieu de:

bool ok = false;
ok ||= f1();
ok ||= f2(); //f2() is called only when f1() returns false
ok ||= f3(); //f3() is called only when f1() or f2() return false
ok ||= f4(); //f4() is called only when ...

Je le conseil à la suite plus compréhensible alternative:

bool ok = false;
if (!ok) ok = f1();
if (!ok) ok = f2();
if (!ok) ok = f3();
if (!ok) ok = f4();
// no comment required here (code is enough understandable)

ou si vous préférez le tout dans une ligne du style:

// this comment is required to explain to developers that 
// f2() is called only when f1() returns false, and so on...
bool ok = f1() || f2() || f3() || f4();

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