Pourquoi utiliser !! lors de la conversion de int bool?
Ce qui peut être une raison pour la conversion d'un nombre entier d'une valeur booléenne de cette façon?
bool booleanValue = !!integerValue;
au lieu de simplement
bool booleanValue = integerValue;
Tout ce que je sais, c'est que dans VC++7 ce dernier va provoquer C4800 avertissement et l'ancien ne sera pas. Est-il une autre différence entre les deux?
- Après la double négation, la valeur est garantie 0 ou 1; la valeur d'origine pourrait être n'importe quelle valeur int.
- Mais pourquoi la deuxième instruction de ne pas faire exactement la même chose?
- Je suppose que la question est pourquoi les anciens ne cause pas un C4800 soit depuis même "le Casting de l'expression de type booléen ne sera pas désactiver l'avertissement, qui est par la conception." (MS)
- pourquoi ne pas plus de gens de suggérer dans le fait que c'est la bonne réponse. double négatif est très commun dans le code bas-niveau
- euh, en fait, cela a sa place... les gens sont confus C++ et de C
Vous devez vous connecter pour publier un commentaire.
Les problèmes avec les "!!" l'idiome qu'il est laconique, difficile à voir, facile à tort d'une faute de frappe, facile à déposer l'un de l' "!'s", et ainsi de suite. Je l'ai mis dans les "regardez comme c'est mignon que nous pouvons être avec C/C++" de la catégorie.
Il suffit d'écrire
bool isNonZero = (integerValue != 0);
... être clair.!!
truc.!!i
est préférable dei != 0
, ou quoi? Si oui, pouvez-vous donner un exemple?!!
comme un "truc" ci-dessus, pas de traitement de zéros et de pointeurs null et faux en C++. Ce dernier est, par conception, et est largement reconnue, comprise et pratiquée dans idiomatiques C++, donc il n'y a pas de problème de lisibilité lors de son utilisation (et il est en outre pris en charge par la bibliothèque standard, qui utilise vérité vérifie par exemple, dans un ruisseau). Le premier est en effet un obscur truc qui est vu très rarement.zero
parce que la norme dit, mais est1
le meilleur choix à utiliser pour représentertrue
dans une forme entière, je serais tenté avec-1
sur la base que tous les bits set (n'est-ce pas) plutôt que de simplement le LSB - ou est-il une raison de ne pas le faire?Historiquement, la
!!
idiome a été utilisé pour s'assurer que votre bool contient l'une des deux valeurs attendues dans unbool
-comme variable, parce que le C et le C++ n'ont pas de vraibool
type et nous truqué avecint
s. C'est moins un problème maintenant, avec de "vrais"bool
s.Mais en utilisant
!!
est un moyen efficace de documentation (pour le compilateur et à tous les futurs personnes qui travaillent dans votre code) que oui, vous avez vraiment a l'intention de lancer cetteint
à unbool
.List<String>
signifie au premier, que ce soit, ou||=
.!!
est un très, très profondément enracinée dans l'idiome dans le C et le C++ univers. Si quelqu'un ne le sait pas, il/elle doit l'apprendre, et ensuite faire leur propre évaluation motivée sur l'opportunité de l'utiliser.bool var = (bool)intVar;
?Il est utilisé parce que le langage C (et quelques pré-standard compilateurs C++ trop) n'a pas eu le
bool
type, justeint
. Ainsi, leint
s ont été utilisés pour représenter des valeurs logiques:0
était censé signifierfalse
, et tout le reste étaittrue
. Le!
opérateur était de retour1
de0
et0
de tout le reste. Double!
a été utilisé pour inverser les, et il était là pour s'assurer que la valeur est juste0
ou1
en fonction de sa valeur logique.En C++, depuis l'adoption d'une bonne
bool
type, il n'y a pas besoin de faire cela. Mais vous ne pouvez pas simplement mettre à jour toutes les anciennes sources, et vous ne devriez pas avoir à, des raisons de compatibilité descendante de C à C++ (la plupart du temps). Mais beaucoup de gens le font encore, de la même raison: pour rester leur code en arrière-compatible avec les anciens compilateurs qui ne comprends toujours pasbool
s.Et c'est la seule vraie réponse. D'autres réponses sont trompeuses.
Parce que !integerValue signifie integerValue == 0 et!integerValue signifie donc integerValue != 0, une expression valide de retourner un booléen. Ce dernier est une fonte avec perte d'information.
Une autre option est l'opérateur ternaire qui semble générer une ligne de moins de code assembleur (dans Visual Studio 2005, de toute façon):
qui produit le code assembleur:
Contre:
qui produit:
Je sais que ce n'est pas une énorme différence, mais j'étais curieux à ce sujet et juste pensé que je voudrais partager mes découvertes.
Un booléen ne peut avoir que deux états, 0 et 1. Un entier peut avoir n'importe quel état de -2147483648 à 2147483647 en supposant un entier signé de 32 bits. Unaire ! opérateur de sorties 1 si l'entrée est 0 et sorties 0 si l'entrée est tout sauf 0. Afin de !0 = 1 et !234 = 0. Le deuxième ! passe simplement la sortie de sorte que 0 devient 1 et 1 devient 0.
De sorte que la première déclaration des garanties que booleanValue sera égal à 0 ou 1 et aucune autre valeur, la deuxième déclaration n'est pas.
int
->bool
exprimés. C'est bien définie, et zéroint
seront convertis entrue
, et 0 seront convertis enfalse
. L'avertissement que VC++ donne il est en fait un "avertissement sur les performances", et n'a rien à voir avec cela.!!
est un idiomatiques façon de convertirbool
, et cela fonctionne pour fermer le compilateur Visual C++ est sillywarning alléguée de l'inefficacité d'une telle conversion.Je vois d'ici les autres réponses et les commentaires que beaucoup de gens ne sont pas familiers avec cet idiome de l'utilité dans la programmation Windows. Ce qui signifie qu'ils n'ont pas fait de sérieux de la programmation sous Windows. Et d'assumer aveuglément que ce qu'ils ont rencontrés est représentatif (il ne l'est pas).
Et au moins une personne pense que si une totale novice ne reconnaît pas son sens, alors c'est ungood. Eh bien, c'est stupide. Il y a beaucoup de choses que de proférer des novices de ne pas reconnaître ou comprendre. L'écriture d'un code de façon à ce qu'il sera entendu par une totale novice n'est pas quelque chose que pour les professionnels. Même pas pour les étudiants. Départ sur le chemin de l'exclusion des opérateurs et de l'opérateur combinaisons de proférer des novices ne reconnaissent pas... eh Bien je n'ai pas les mots pour donner à cette approche une description appropriée, désolé.
Cheers & hth.,
La réponse de user143506 est correct mais pour un possible problème de performances, j'ai comparé la possibilies en asm:
return x;
,return x != 0;
,return !!x;
et mêmereturn boolean_cast<bool>(x)
résultats dans cette parfaite panoplie de l'asm instructions:Cela a été testé pour GCC 7.1 et MSVC 19 2017. (Seul le boolean_converter dans MSVC 19 2017 résultats dans une plus grande quantité de asm-code, mais cela est causé par templatization et les structures, et peuvent être négligés par le point de vue des performances, parce que les mêmes lignes comme indiqué ci-dessus peut juste dupliqué pour les différentes fonctions avec le même runtime.)
Cela signifie: Il n'y a pas de différence de performances.
PS: Ce boolean_cast a été utilisée:
Pas de grande raison si ce n'est être paranoïaque ou crier à l'aide de code que c'est un bool.
pour le compilateur à la fin il l'habitude de faire la différence .
Je n'ai jamais comme cette technique de la conversion en
bool
type de données - ça sent mauvais!Au lieu de cela, nous utilisons un modèle de pratique appelée
boolean_cast
trouvé ici. C'est une solution flexible qui est plus explicite dans ce qu'il fait et peut être utilisé comme suit: