45 votes

Que se passe-t-il si une énumération ne peut pas entrer dans un type entier non signé?

Comme demandé par bath-schéba, et comme une question de suivi à "Ce qui se passe si une enum ne peut pas correspondre à un type intégral?":

En un enum est définie comme suit :

enum foo : unsigned int
{
    bar = UINT_MAX,
    oops
};

Est la valeur de oops défini ou n'est-ce pas?


MSVS2015 de la compilation:

warning C4340: 'oops': value wrapped from positive to negative value
warning C4309: 'initializing': truncation of constant value
warning C4369: 'oops':  enumerator value '4294967296' cannot be represented as 'unsigned int', value is '0'

MSVS2015 de sortie:

bar = 4294967295
oops= 0

gcc 4.9.2 compilation:

9 : note: in expansion of macro 'UINT_MAX'
bar = UINT_MAX,
^
10 : error: enumerator value 4294967296l is outside the range of underlying type 'unsigned int'
oops
^
Compilation failed

gcc 4.9.2 sortie

//compilation failed

19voto

Shmuel H. Points 1292

C'est une question très intéressante. La réponse est simple, c'est littéralement indéfini: la norme ne dit rien à propos de cette affaire.

Pour avoir un meilleur exemple, prenons cette enum:

 enum foo : bool { True=true, undefined };

Selon la norme:

[dcl.enum]/2: [...] Un agent recenseur, définition sans un initialiseur donne à l' agent recenseur à la valeur obtenue par l'augmentation de la valeur de la précédente agent recenseur par un.

Par conséquent, la valeur de foo::undefined dans notre exemple, est - 2 (true+1). Qui ne peut pas être représenté comme un bool.

Est-il mal formé?

Non, selon la norme, il est parfaitement valide, seule la non-correction d'un type sous-jacent ont une restriction de ne pas être en mesure de représenter l'ensemble de l'énumérateur valeurs:

[dcl.enum]/7: Pour une énumération dont le type sous-jacent n'est pas fixe, [...] Si aucun type intégral peut représenter toutes les énumérateur des valeurs de l'énumération est mal formé.

Il ne dit rien sur un fixe sous-jacent type qui ne peut pas représenter tous les énumérateur de valeurs.

Quelle est la valeur de l'original de la question de l' oops et undefined?

Il est pas défini: la norme ne dit rien à propos de cette affaire.

Les valeurs possibles pour foo::undefined:

  • Plus haute valeur possible (true): undefined et oops devrait être de type sous-jacent'valeur maximale.
  • La plus faible valeur possible (false): le type sous-jacent'valeur minimale. Remarque: En nombres entiers signés, il ne serait pas conforme au comportement actuel de dépassement d'Entier (comportement indéfini).
  • Valeur aléatoire (?): le compilateur de choisir une valeur.

Le problème avec l'ensemble de ces valeurs, c'est qu'il peut résulter de deux champs avec la même valeur (par exemple, foo::True == foo::undefined).

La différence entre l'initialiseur (par exemple, undefined=2) et "implicite" de l'initialiseur (par exemple, True=true, undefined)

Selon la norme:

[dcl.enum]/5: Si le sous-jacent est de type fixe, le type de chaque agent recenseur avant l'accolade fermante est le type sous-jacent et de la constante de l'expression de l' agent recenseur, la définition doit être converti expression constante du type sous-jacent.

En d'autres termes:

 enum bar : bool { undefined=2 };

est équivalent à

 enum bar : bool { undefined=static_cast<bool>(2) };

Et puis, bar::undefined sera true. Dans "implicite" de l'initialiseur, il ne serait pas le cas: ce paragraphe standard de dire ça à propos de seulement initialiseur, et pas sur "implicite" de l'initialiseur.

Résumé

  1. Avec cette façon, il est possible pour un enum avec un fixe sous-jacents de type à avoir irreprésentable valeurs.
  2. Leur valeur n'est pas définie par la norme.

Selon la question et les commentaires, ce n'est pas valable dans GCC et clang mais valable pour MSVS-2015 (avec un avertissement).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X