Y a-t-il une "très mauvaise chose" qui peut arriver &&=
et qui a ||=
été utilisée comme sucre syntaxique pour bool foo = foo && bar
et bool foo = foo || bar
?
c++
boolean-operations
Kache
la source
la source
x ||= y
peu près équivalent à C ++x = x ? x : y;
pour aucun type? En d'autres termes, "mis à y si ce n'est déjà fait". C'est considérablement plus utile que C ou C ++x ||= y
, qui (à l'exception de la surcharge des opérateurs) ferait "définir x à(bool)y
sauf s'il est déjà défini". Je ne suis pas impatient d'ajouter un autre opérateur pour cela, cela semble un peu faible. Écrivez justeif (!x) x = (bool)y
. Mais alors, je n'utilise pas vraimentbool
assez de variables pour vouloir des opérateurs supplémentaires qui ne sont vraiment utiles qu'avec ce type.&&=
ou||=
est simplement que C ne les a pas. Je suis raisonnablement sûr que la raison pour laquelle C ne les a pas est que la fonctionnalité n'a pas été jugée suffisamment bénéfique.bool foo = foo || bar;
invoquerait un comportement non défini car ellefoo
n'est pas initialisée avant l'évaluation defoo || bar
. Bien sûr, cela est censé être quelque chose commebool foo = …initialization…; …; foo = foo || bar;
et la question est alors valide.Réponses:
Un
bool
peut être uniquementtrue
oufalse
en C ++. En tant que tel, utiliser&=
et|=
est relativement sûr (même si je n'aime pas particulièrement la notation). Certes, ils effectueront des opérations sur les bits plutôt que des opérations logiques (et donc ils ne court-circuiteront pas) mais ces opérations sur les bits suivent un mappage bien défini, qui est effectivement équivalent aux opérations logiques, tant que les deux opérandes sont de typebool
. 1Contrairement à ce que d'autres ont dit ici, un
bool
en C ++ ne doit jamais avoir une valeur différente telle que2
. Lors de l'attribution de cette valeur à abool
, elle sera convertietrue
en selon la norme.La seule façon d'obtenir une valeur non valide dans a
bool
est d'utiliser desreinterpret_cast
pointeurs:Mais comme ce code entraîne de toute façon un comportement indéfini, nous pouvons ignorer en toute sécurité ce problème potentiel lors de la conformité du code C ++.
1 Certes, c'est une mise en garde assez importante comme l'illustre le commentaire d'Angew:
La raison en est que
b & 2
effectue une promotion entière de telle sorte que l'expression soit alors équivalente àstatic_cast<int>(b) & 2
, ce qui entraîne0
, qui est ensuite reconvertie en un fichierbool
. Il est donc vrai que l'existence d'un systèmeoperator &&=
améliorerait la sécurité des types.la source
||
et&&
raccourci, c'est-à-dire que le deuxième argument n'est pas un opérande si le premier opérande esttrue
(resp.false
pour&&
).|
,&
,|=
Et&=
toujours évaluer les deux opérandes.&=
pour un côté gauche de typebool
, car il est parfaitement possible que le côté droit soit de type autre quebool
(commeislower
ou une autre fonction C stdlib qui renvoie une valeur différente de zéro pour la valeur vraie). Si nous avions l'hypothèse&&=
, cela forcerait probablement le membre de droite à se convertirbool
, ce qui&=
n'est pas le cas. En d'autres termes,bool b = true; b &= 2;
aboutit àb == false
.&&
et&
ont une sémantique différente:&&
n'évaluera pas le deuxième opérande si le premier opérande estfalse
. c'est-à-dire quelque chose commeest sûr, mais
n'est pas, bien que les deux opérandes soient de type
bool
.La même chose est vraie pour
&=
et|=
:se comportera différemment de:
la source
Réponse courte
Tous les opérateurs
+=
,-=
,*=
,/=
,&=
,|=
... sont l' arithmétique et offrent même attente:Cependant, les opérateurs
&&=
et||=
seraient logiques, et ces opérateurs pourraient être sujets aux erreurs car de nombreux développeurs s'attendent àfoo()
être toujours appelésx &&= foo()
.Avons-nous vraiment besoin de rendre C / C ++ encore plus complexe pour obtenir un raccourci
x = x && foo()
?Voulons-nous vraiment obscurcir davantage la déclaration cryptique
x = x && foo()
?Ou voulons-nous écrire du code significatif comme
if (x) x = foo();
?Longue réponse
Exemple pour
&&=
Si l'
&&=
opérateur était disponible, alors ce code:est équivalent à:
Ce premier code est sujet aux erreurs car de nombreux développeurs penseraient qu'il
f2()
est toujours appelé quelle que soit laf1()
valeur renvoyée. C'est comme écrirebool ok = f1() && f2();
oùf2()
n'est appelé que lors duf1()
retourtrue
.f2()
être appelé uniquement lors desf1()
retourstrue
, le deuxième code ci-dessus est donc moins sujet aux erreurs.f2()
toujours être appelé),&=
suffit:Exemple pour
&=
De plus, il est plus facile pour le compilateur d'optimiser ce code ci-dessus que celui du dessous:
Comparez
&&
et&
On peut se demander si les opérateurs
&&
et&
donnent le même résultat lorsqu'ils sont appliqués sur desbool
valeurs?Vérifions en utilisant le code C ++ suivant:
Production:
Conclusion
Par conséquent OUI, nous pouvons remplacer
&&
par&
desbool
valeurs ;-)Donc, mieux vaut utiliser
&=
au lieu de&&=
.Nous pouvons considérer
&&=
comme inutile pour les booléens.Pareil pour
||=
Si un développeur souhaite
f2()
être appelé uniquement lors duf1()
retourfalse
, au lieu de:Je conseille l'alternative plus compréhensible suivante:
ou si vous préférez tout dans un style de ligne :
la source
success = success && DoImportantStuff()
if(success) success = DoImportantStuff()
. Si l'instructionsuccess &&= DoImportantStuff()
était autorisée, de nombreux développeurs penseraient qu'elleDoImportantStuff()
est toujours appelée quelle que soit la valeur desuccess
. J'espère que cela répond à ce que vous vous demandez ... J'ai également amélioré de nombreuses parties de ma réponse. Veuillez me dire si ma réponse est plus compréhensible maintenant? (à propos de votre commentaire) Cheers, See you ;-)success &&= DoImportantStuff()
était autorisée, de nombreux développeurs penseraient qu'elleDoImportantStuff()
est toujours appelée quelle que soit la valeur du succès." Vous pouvez en direif (success && DoImportantStuff())
autant. Tant qu'ils se souviennent de la logique derrière la syntaxe if, ils ne devraient avoir aucun problème avec&&=
.f1()
évalue toujoursok &&= f(1)
mais ne supposera pas que cela évalue toujoursok = ok && f(1)
. Cela me semble tout aussi probable.v1 += e2
à être l'équivalent en sucre syntaxique de lav1 = v1 + e1
variable v1 et de l'expression e2. Juste une notation abrégée, c'est tout.