Uint8_t peut-il être un type sans caractère?

Dans cette réponse et les commentaires joints, Pavel Minaev avance l’argument suivant selon lequel, en C, les seuls types auxquels uint8_t peut être typé sont les caractères char et unsigned char . Je regarde ce projet de norme C.

  • La présence de uint8_t implique la présence du type correspondant int8_t (7.18.1p1).
  • int8_t largeur de 8 bits et n’a pas de bits de remplissage (7.18.1.1p1).
  • Les types correspondants ont la même largeur (6.2.5p6), donc uint8_t également une largeur de 8 bits.
  • unsigned char est CHAR_BIT bits de large (5.2.4.2.1p2 et 6.2.6.1p3).
  • CHAR_BIT est au moins 8 (5.2.4.2.1p1).
  • CHAR_BIT est au plus CHAR_BIT à 8, car uint8_t est un caractère unsigned char , ou un type non- unsigned char , de type champ non-bit, dont la largeur est un multiple de CHAR_BIT (6.2.6.1p4).

Sur la base de cet argument, je conviens que, si uint8_t existe, alors lui et le caractère unsigned char ont des représentations identiques: 8 bits de valeur et 0 bits de remplissage. Cela ne semble pas les obliger à être du même type (par exemple, 6.2.5p14).

Est-il permis que uint8_t soit typé avec un type entier étendu non signé (6.2.5p6) avec la même représentation que unsigned char ? Certes, il doit être typedef’d (7.18.1.1p2), et il ne peut s’agir d’aucun type d’entier standard non signé autre que unsigned char (ou char s’il est non signé). Ce type étendu hypothétique ne serait pas un type de caractère (6.2.5p15) et ne pourrait donc pas prétendre à un access avec alias à un object d’un type incompatible (6.5p7), ce qui me semble être la raison pour laquelle un rédacteur du compilateur voudrait le faire. chose.

Si uint8_t existe, l’exigence de non-remplissage signifie que CHAR_BIT est CHAR_BIT 8. Cependant, il n’existe aucune raison fondamentale pour laquelle uint8_t ne peut pas être défini avec un type entier étendu . De plus, rien ne garantit que les déclarations sont les mêmes; par exemple, les bits pourraient être interprétés dans l’ordre inverse.

Bien que cela semble stupide et gratuitement inhabituel pour uint8_t , cela pourrait avoir beaucoup de sens pour int8_t . Si une machine utilise en mode natif son complément ou son signe / magnitude, alors le caractère signed char ne convient pas pour int8_t . Cependant, il pourrait utiliser un type entier étendu signé qui émule le complément à deux pour fournir int8_t .

Au 6.3.1.1 (1) (du projet N1570 de la norme C11), on peut lire

Le rang de tout type entier standard doit être supérieur à celui de tout type entier étendu de même largeur.

La norme autorise donc explicitement la présence de types entiers étendus de la même largeur qu’un type entier standard.

Rien dans la norme n’interdit une

 typedef implementation_defined_extended_8_bit-unsigned_integer_type uint8_t; 

si ce type entier étendu correspond aux spécifications de uint8_t (pas de bits de remplissage, largeur de 8 bits), autant que je uint8_t .

Donc oui, si l’implémentation fournit un tel type entier étendu, uint8_t peut être typé pour cela.

uint8_t peut exister et être un type distinct de unsigned char .

Une implication significative de ceci est dans la résolution de surcharge; cela dépend de la plate-forme si:

 uint8_t by = 0; std::cout << by; 

les usages

  1. operator<<(ostream, char)
  2. operator<<(ostream, unsigned char) ou
  3. operator<<(ostream, int)

int8_t et uint8_t ne diffèrent que par REPRESENTATION et PAS par le contenu (bits). int8_t utilise 7 bits inférieurs pour les données et le 8ème bit doit représenter le “signe” (positif ou négatif). Par conséquent, la plage de int8_t va de -128 à +127 (0 est considéré comme une valeur positive).

uint8_t a également une largeur de 8 bits, MAIS les données qu’il contient sont TOUJOURS positives. La plage de uint8_t va donc de 0 à 255.

Compte tenu de ce fait, char est large de 8 bits. Un caractère non signé aurait également une largeur de 8 bits, mais sans le “signe”. De manière similaire, short et unsigned short ont tous deux une largeur de 16 bits.

Cependant, si ” unsigned int ” a une largeur de 8 bits, alors .. puisque C n’est pas trop typé-nazi, il est permis. Et pourquoi un rédacteur de compilateur permettrait-il une telle chose? LISIBILITÉ!