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, [..]
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.
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.
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 ++.
«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.
assert(x!=0)
. Même si bool (true) convertit portable en int (1), les assertions "not false" ont une expression plus lisible.assert( 4 < 5);
etassert(!( 4 > 5));
(4 < 5) ? 1 : 0
si 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.Réponses:
Complètement portable. Conforme à la norme.
bool
laint
conversion est implicite!§4.7 / 4 de la norme C ++ dit ( Conversion intégrale )
En ce qui concerne C, pour autant que je sache , il n'y a pas
bool
de C. (avant 1999) Donc ,bool
à laint
conversion est pertinente en C ++ uniquement. Dans C,4<5
évalue àint
valeur, dans ce cas, la valeur est1
,4>5
serait évaluée à0
.EDIT: Jens dans le commentaire dit, C99 a du
_Bool
type.bool
est une macro définie dans lestdbool.h
fichier d' en- tête.true
etfalse
sont également définis par macro dansstdbool.h
.§7.16 de C99 dit,
la source
bool
en C depuis 1999. Utilisez simplement l'en-tête "stdbool.h" et cela devrait être inclus.bool
/_Bool
type, les opérateurs relationnels en C produisentint
, nonbool
. C'est-à-dire même en C99, les opérateurs relationnels produisent toujoursint
.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
bool
quoi que ce soit (cela s'applique également à C99). En langage C, les opérateurs relationnels ne produisent pas debool
résultats. Les deux4 > 5
et4 < 5
sont des expressions qui produisent des résultats de typeint
avec des valeurs0
ou1
. 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
bool
résultats.bool
les valeurs sont convertibles enint
type, avectrue
conversion1
etfalse
conversion en0
. Ceci est garanti par la langue.Le langage PS C a également un type booléen dédié
_Bool
(macro-aliasé en tant quebool
), 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 toujoursint
(pasbool
) des résultats quelle que soit la version de la spécification du langage.la source
bool
en C99, les opérateurs relationnels produisent toujoursint
en C99, nonbool
. 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 avecbool
.int
, pas unbool
. Aucune conversion ne se produit.bool
mais 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'identifiantbit
). Sur par exemple un PIC de milieu de gamme, il yif (bitVar1) bitVar2=1;
aurait deux instructions; le codage optimal pourif (byteVar1) byteVar2=1;
serait au moins quatre (sur de nombreux compilateurs, probablement cinq). De tels types peuvent ainsi offrir un gain de performances majeur.La section 6.5.8.6 de la norme C dit:
la source
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 ++.
la source