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
?
Réponses
Trop de publicités?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++.
&&
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();
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();
où f2()
n'est appelé que lorsque f1()
retours true
.
- Si le développeur veut réellement
f2()
seulement lors de l'f1()
retourstrue
, 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();