conversion booléenne en int

131

Quelle est la portabilité de cette conversion. Puis-je être sûr que les deux affirmations sont acceptées?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

Ne demande pas pourquoi. Je sais que c'est moche. Je vous remercie.

pic11
la source
Pourquoi ne changez-vous pas la première expression? Vous pouvez écrire assert(x!=0). Même si bool (true) convertit portable en int (1), les assertions "not false" ont une expression plus lisible.
harper
1
Pourquoi pas: assert( 4 < 5);etassert(!( 4 > 5));
Martin York
4
@harper: L'utilisation de la valeur requise d'une expression de comparaison est parfaitement raisonnable.
R .. GitHub STOP AIDER ICE
@ R._ Quand la question est de savoir si la conversion bool-en-int donne un résultat raisonnable, je ne me fierais pas à cela. Lorsque l'auteur a un doute que cette exigence est remplie, le lecteur pourrait avoir le même problème. D'autant que la valeur de x n'est pas la condition à vérifier mais seulement un résultat intermédiaire.
harper
3
J'écrirais probablement (4 < 5) ? 1 : 0si j'ai vraiment besoin de convertir un booléen en 0 ou 1. Un bon compilateur produira probablement le même code machine et c'est plus clair pour un lecteur humain.
ollb

Réponses:

205
int x = 4<5;

Complètement portable. Conforme à la norme. boolla intconversion est implicite!

§4.7 / 4 de la norme C ++ dit ( Conversion intégrale )

Si le type source est booléen, la valeur falseest convertie en zéro et la valeur trueest convertie en un .


En ce qui concerne C, pour autant que je sache , il n'y a pas boolde C. (avant 1999) Donc , boolà la intconversion est pertinente en C ++ uniquement. Dans C, 4<5évalue à intvaleur, dans ce cas, la valeur est 1, 4>5 serait évaluée à 0.

EDIT: Jens dans le commentaire dit, C99 a du _Booltype. boolest une macro définie dans le stdbool.hfichier d' en- tête. trueet falsesont également définis par macro dans stdbool.h.

§7.16 de C99 dit,

La macro se booldéveloppe en _Bool.

[..] truequi se développe en constante entière 1, false qui se développe en constante entière 0, [..]

Nawaz
la source
3
sûr qu'il existe boolen C depuis 1999. Utilisez simplement l'en-tête "stdbool.h" et cela devrait être inclus.
Jens Gustedt
1
En effet, je l'ai vérifié sur plusieurs compilateurs et il semble portable.
photo11
8
Indépendamment de la version du langage C et de la disponibilité de bool/ _Booltype, les opérateurs relationnels en C produisent int, non bool. C'est-à-dire même en C99, les opérateurs relationnels produisent toujours int.
Du
51

Vous avez marqué votre question [C] et [C ++] en même temps. Les résultats seront cohérents entre les langues, mais la structure de la réponse est différente pour chacune de ces langues.

En langage C, vos exemples n'ont aucun rapport avec boolquoi que ce soit (cela s'applique également à C99). En langage C, les opérateurs relationnels ne produisent pas de boolrésultats. Les deux 4 > 5et 4 < 5sont des expressions qui produisent des résultats de type intavec des valeurs 0ou 1. Donc, il n'y a pas de "conversion bool en int" d'aucune sorte dans vos exemples en C.

En C ++, les opérateurs relationnels produisent en effet des boolrésultats. boolles valeurs sont convertibles en inttype, avec trueconversion 1et falseconversion en 0. Ceci est garanti par la langue.

Le langage PS C a également un type booléen dédié _Bool(macro-aliasé en tant que bool), et ses règles de conversion intégrales sont essentiellement les mêmes qu'en C ++. Mais néanmoins cela n'est pas pertinent pour vos exemples spécifiques en C. Encore une fois, les opérateurs relationnels en C produisent toujours int(pas bool) des résultats quelle que soit la version de la spécification du langage.

Fourmi
la source
2
C'est vrai, il n'y a pas de booléen dans K&R C. J'ai re-taggé ma question en C99.
pic11
@ pic11: Il n'était pas nécessaire de repenser quoi que ce soit. Cela n'a rien à voir avec K&R ou tout autre C. Même s'il y en a boolen C99, les opérateurs relationnels produisent toujours inten C99, non bool. Donc, si ce sont spécifiquement les opérateurs relationnels qui vous intéressent (comme dans vos exemples), le problème n'a toujours rien à voir avec bool.
Du
Maintenant je comprends. Le résultat de l'opérateur de relation convertible implicitement en int. Cela est vrai en C, C99 et C ++. Re-targed à nouveau.
photo11
3
@ pic11: Non, vous ne comprenez pas. En C, y compris C99, le résultat d'un opérateur de comparaison est un int, pas un bool. Aucune conversion ne se produit.
R .. GitHub STOP AIDER ICE
Existe-t-il un moyen conforme aux normes par lequel un langage pourrait avoir un type qui se comporte comme boolmais ne permet pas de prendre son adresse? De nombreux systèmes embarqués utilisent de tels types (souvent déclarés à l'aide de l'identifiant bit). Sur par exemple un PIC de milieu de gamme, il y if (bitVar1) bitVar2=1;aurait deux instructions; le codage optimal pour if (byteVar1) byteVar2=1;serait au moins quatre (sur de nombreux compilateurs, probablement cinq). De tels types peuvent ainsi offrir un gain de performances majeur.
supercat
17

La section 6.5.8.6 de la norme C dit:

Chacun des opérateurs <(inférieur à),> (supérieur à), <= (inférieur ou égal à) et> = (supérieur ou égal à) donnera 1 si la relation spécifiée est vraie et 0 si elle est false.) Le résultat est de type int.


la source
Merci pour la référence. Il semble que vrai == 1 pour des raisons historiques.
pic11
2

Il ne semble y avoir aucun problème puisque le cast int en booléen se fait implicitement. Cela fonctionne dans le compilateur Microsoft Visual C ++, GCC et Intel C ++. Aucun problème en C ou C ++.

Alex James
la source
2
«Cela fonctionne dans certains cas» n'est pas un bon moyen de vérifier l'exactitude, en particulier avec des versions non spécifiées de ces outils. Je préfère l'approche dans les autres réponses; ils ne peuvent pas garantir qu'une implémentation particulière est correcte, mais ils peuvent garantir ce qu'une implémentation correcte fera.
Matthieu Lire