web-dev-qa-db-fra.com

L'opération "false <true" est-elle bien définie?

La spécification C++ définit-elle:

  1. l'existence de l'opérateur "moins de" pour les paramètres booléens, et si oui,
  2. le résultat des 4 permutations des paramètres?

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;
}
153
duncan

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
206
Shafik Yaghmour

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.

63
Mark Ransom

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
22
Vlad from Moscow

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.

8
Blindstealer