La spécification C++ définit-elle:
En d'autres termes, les résultats des opérations suivantes sont-ils définis par la spécification?
false < false
false < true
true < false
true < true
Sur ma configuration (Centos 7, gcc 4.8.2), le code ci-dessous indique ce à quoi je m'attendais (étant donné l'historique de C de représenter false comme 0 et vrai comme 1):
false < false = false
false < true = true
true < false = false
true < true = false
Bien que je sois à peu près sûr que la plupart (tous?) Des compilateurs donneront la même sortie, est-ce prévu par la spécification C++? Ou un compilateur obscurcissant, mais conforme aux spécifications, peut-il décider que vrai est moins que faux?
#include <iostream>
const char * s(bool a)
{
return (a ? "true" : "false");
}
void test(bool a, bool b)
{
std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}
int main(int argc, char* argv[])
{
test(false, false);
test(false, true);
test(true, false);
test(true, true);
return 0;
}
TL; DR:
Les opérations sont bien définies selon le projet de norme C++.
Détails
On peut le voir en allant dans la section projet de norme C++5.9
Opérateurs relationnels qui dit ( je mets l'accent à l'avenir):
Les opérandes doivent être de type arithmétique , énumération ou pointeur , ou type std :: nullptr_t. Les opérateurs <(inférieur à),> (supérieur à), <= (inférieur ou égal à) et> = (supérieur ou égal à) produisent tous faux ou vrai. Le type du résultat est bool
et les bools sont des types arithématiques de 3.9.1 Types fondamentaux
Les types bool , char, char16_t, char32_t, wchar_t et les types entiers signés et non signés sont collectivement appelés types intégraux .
et
Les types intégraux et flottants sont collectivement appelés types arithmétiques.
et true
et false
sont des littéraux booléens de 2.14.6
Littéraux booléens:
boolean-literal:
false
true
Revenir à la section 5.9
pour voir plus en détail la mécanique des opérateurs relationnels:
Les conversions arithmétiques habituelles sont effectuées sur des opérandes de type arithmétique ou énumération.
les conversions arithmétiques habituelles sont traitées dans la section 5
qui dit:
Sinon, les promotions intégrales (4.5) doivent être effectuées sur les deux opérandes
et section 4.5
dit:
Une valeur de type bool peut être convertie en valeur de type int, false devenant nul et true devenant un.
et donc les expressions:
false < false
false < true
true < false
true < true
l'utilisation de ces règles devient:
0 < 0
0 < 1
1 < 0
1 < 1
Les valeurs booléennes sont soumises aux promotions entières habituelles, avec false
défini comme 0
et true
définis comme 1
. Cela rend toutes les comparaisons bien définies.
Selon la norme C++ (5.9 Opérateurs relationnels)
2 Les conversions arithmétiques habituelles sont effectuées sur des opérandes de type arithmétique ou énumération.
et
1 ... Le type du résultat est bool.
et (3.9.1 Types fondamentaux)
6 Les valeurs de type bool sont vraies ou fausses.49 [Remarque: Il n'y a pas de type ou de valeur booléen signé, non signé, court ou long. —Fin note] Les valeurs de type bool participent aux promotions intégrales (4.5).
et (4.5 promotions intégrales)
6 Une valeur de type bool peut être convertie en valeur de type int, avec false devenant zéro et true devenant un.
Donc, dans tous vos exemples, true est converti en int 1 et false est converti en int 0
Ces expressions
false < false
false < true
true < false
true < true
sont entièrement équivalents à
0 < 0
0 < 1
1 < 0
1 < 1
Boolean false
est équivalent à int 0
, et booléen true
est équivalent à int 1
. Cela explique donc pourquoi l'expression false < true
=> 0 < 1
est le seul qui renvoie true
.