Est-ce que le caractère garanti a exactement 8 bits de long?

C’est tout. Je n’ai pas trouvé de sujet similaire, alors prenez-le avec moi.

À partir d’ une copie de la spécification ANSI C , reportez-vous à la Section 3.1.2.5 – Types :

Un object déclaré comme type char est suffisamment grand pour stocker n’importe quel membre du jeu de caractères d’exécution de base. Si un membre du jeu de caractères source énuméré dans $ 2.2.1 est stocké dans un object char, sa valeur est garantie. Si d’autres quantités sont stockées dans un object char, le comportement est défini par l’implémentation: les valeurs sont traitées comme des entiers signés ou non.

Le concept de “jeu de caractères d’exécution” est présenté au paragraphe 2.2.1 – Jeux de caractères .

En d’autres termes, un caractère doit être au moins assez grand pour contenir un encodage d’au moins 95 caractères différents constituant le jeu de caractères d’exécution de base.

Maintenant, ajoutez à cela la section 2.2.4.2 – Limites numériques

Une implémentation conforme doit documenter toutes les limites spécifiées dans cette section, qui doivent être spécifiées dans les en-têtes et .

Tailles de types intégraux

Les valeurs indiquées ci-dessous doivent être remplacées par des expressions constantes pouvant être utilisées dans les directives de prétraitement #if. Leurs valeurs définies par la mise en œuvre doivent être égales ou supérieures (valeur absolue) à celles indiquées, avec le même signe.

  • nombre maximal de bits pour le plus petit object qui n’est pas un champ binary (octet)
    CHAR_BIT 8

  • valeur minimale pour un object de type signé char
    SCHAR_MIN -127

  • valeur maximale pour un object de type signé char
    SCHAR_MAX +127

  • valeur maximale pour un object de type unsigned char
    UCHAR_MAX 255

….

Donc là vous l’avez – le nombre de bits dans un caractère doit être d’au moins 8.

Non, il n’est pas garanti que ce soit 8 bits. sizeof (char) est garanti 1, mais cela ne signifie pas nécessairement un octet de 8 bits.

non, le type de données char doit contenir au moins 8 bits (voir la spécification C ANSI)

Le brouillon standard C99 indique qu’un octet doit avoir une largeur d’au moins 8 bits, car contient une macro CHAR_BIT qui donne le nombre de bits par octet et qui est garantie à au moins 8 (§5.2.4.2. 1).

Le brouillon standard C ++ inclut les sous le nom (§18.2.2).

Voyons exactement ce que dit la norme:

5.2.4.2.1 Tailles des types entiers

Leurs valeurs de mise en œuvre doivent être égales ou supérieures (valeur absolue) à celles indiquées, avec le même signe.


nombre de bits pour le plus petit object qui n’est pas un champ de bits (octet)
CHAR_BIT 8

Cela nous dit qu’un octet est au moins 8 bits (le paragraphe ci-dessus

Si la valeur d’un object de type char est traitée comme un entier signé lorsqu’il est utilisé dans une expression, la valeur de CHAR_MIN doit être identique à celle de SCHAR_MIN et la valeur de CHAR_MAX doit être identique à celle de SCHAR_MAX. Sinon, la valeur de CHAR_MIN doit être 0 et la valeur de CHAR_MAX doit être identique à celle de UCHAR_MAX. La valeur UCHAR_MAX doit être égale à 2 ^ CHAR_BIT – 1


Pour chacun des types d’entiers signés, il existe un type d’entier non signé correspondant (mais différent) (désigné par le mot-clé non signé) qui utilise la même quantité de stockage (y compris les informations de signe) et présente les mêmes exigences d’alignement.


Pour les types d’entiers non signés autres que les caractères non signés, les bits de la représentation d’object doivent être divisés en deux groupes: les bits de valeur et les bits de remplissage (il n’y a pas besoin de ces derniers).

Ces passages nous disent que:

  • un caractère non signé doit représenter 2 valeurs ^ CHAR_BIT-1, qui peuvent être codées sur des bits CHAR_BIT minimum (conformément à la représentation des bits conventionnelle, qui est prescrite par la norme)
  • un caractère non signé ne contient aucun bit supplémentaire (de remplissage)
  • un caractère signé prend exactement le même espace qu’un caractère non signé
  • un caractère est implémenté de la même manière que le caractère signé ou non signé

Conclusion: les caractères non signés et les caractères non signés d’un char et de ses variantes ont exactement la taille d’un octet et un octet est garanti d’au moins 8 bits.

Maintenant, ce sont d’autres indications (mais pas de preuve formelle comme ci-dessus) qu’un caractère est bien un octet:

À l’exception des champs de bits, les objects sont composés de séquences contiguës d’un ou plusieurs octets, dont le nombre, l’ordre et le codage sont explicitement spécifiés ou définis par l’implémentation.


Les valeurs stockées dans des objects de champs non binarys de tout autre type d’object sont constituées de n × bits CHAR_BIT, où n est la taille d’un object de ce type, en octets. La valeur peut être copiée dans un object de type unsigned char [n]


L’opérateur sizeof donne la taille (en octets) de son opérande, qui peut être une expression ou le nom entre parenthèses d’un type. La taille est déterminée à partir du type de l’opérande. Le résultat est un entier. Si le type de l’opérande est un type de tableau de longueur variable, l’opérande est évalué; sinon, l’opérande n’est pas évalué et le résultat est une constante entière.


Lorsqu’il est appliqué à un opérande ayant un type char, un caractère non signé ou un caractère signé (ou une version qualifiée de celui-ci), le résultat est 1. Lorsqu’il est appliqué à un opérande de type tableau, le résultat est le nombre total d’octets du tableau. . 88) Lorsqu’il est appliqué à un opérande de type structure ou union, le résultat est le nombre total d’octets dans un tel object, y compris le remplissage interne et le remplissage.

(Notez qu’il y a une ambiguïté ici. Le sizeof (char) ici remplace-t-il la règle sizeof (type) ou ne donne-t-il qu’un exemple?)

Cependant, il rest un problème à régler. Qu’est-ce qu’un octet exactement? Selon le standard, c’est “le plus petit object qui n’est pas un champ de bits”. Notez que cela peut théoriquement ne pas correspondre à un octet de machine , et qu’il y a aussi une ambiguïté quant à ce que l’on appelle un “octet de machine”: il pourrait tout ce que les constructeurs appellent “octet”, sachant que chaque constructeur peut avoir un autre définition de “octet”; ou une définition générale telle que “une séquence de bits qu’un ordinateur traite en unités individuelles” ou “le plus petit bloc de données adressable”.

Par exemple, une machine ayant des octets de 7 bits devrait implémenter un “octet C” en deux octets de machine.

Source de toutes les citations: Projet de comité – 7 septembre 2007 ISO / IEC 9899: TC3 .

A partir de la norme C décrivant limits.h (un certain reformatage requirejs):

  1. nombre de bits pour le plus petit object qui n’est pas un champ binary (octet): CHAR_BIT 8
  2. valeur minimale pour un object de type signé char: SCHAR_MIN -127
  3. valeur maximale pour un object de type signé char: SCHAR_MAX +127

CHAR_BIT minimum de 8 garantit qu’un caractère a au moins 8 bits de large. Les plages sur SCHAR_MIN et SCHAR_MAX garantissent que la représentation d’un caractère signé utilise au moins huit bits.

La première chose que je dirais est que si vous avez besoin d’un type pour avoir un nombre exact de bits, utilisez un type spécifique à la taille. Selon votre plate-forme, cela peut aller de __s8 pour un type 8 bits signé sous Linux à __int8 dans VC ++ sous Windows.

Maintenant, selon Robert Love dans son chapitre sur la portabilité dans “Linux Kernel Development”, il déclare que le standard C “laisse la taille des types standard aux implémentations, bien qu’elle impose une taille minimale”.

Puis, dans une note en bas de page, il dit: “A l’exception du caractère qui est toujours de 8 bits”

Maintenant, je ne sais pas sur quoi il se base, mais c’est peut-être cette section de la spécification ANSI C ?

2.2.4.2 Limites numériques

Une implémentation conforme doit documenter toutes les limites spécifiées dans cette section, qui doivent être spécifiées dans les en-têtes limits.h et float.h

“Tailles de types intégraux limites.h”

Les valeurs indiquées ci-dessous doivent être remplacées par des expressions constantes pouvant être utilisées dans les directives de prétraitement #if. Leurs valeurs définies par la mise en œuvre doivent être égales ou supérieures (valeur absolue) à celles indiquées, avec le même signe.

nombre maximal de bits pour le plus petit object qui n’est pas un champ binary (octet)

CHAR_BIT 8

valeur minimale pour un object de type signé char

SCHAR_MIN -127

valeur maximale pour un object de type signé char

SCHAR_MAX +127

valeur maximale pour un object de type unsigned char

UCHAR_MAX 255

valeur minimale pour un object de type char

CHAR_MIN voir ci-dessous

valeur maximale pour un object de type char

CHAR_MAX voir ci-dessous

nombre maximal d’octets dans un caractère multi-octets, pour tout paramètre régional pris en charge

MB_LEN_MAX 1

valeur minimale pour un object de type short int

SHRT_MIN -32767

valeur maximale pour un object de type short int

SHRT_MAX +32767

valeur maximale pour un object de type unsigned short int

USHRT_MAX 65535

valeur minimale pour un object de type int

INT_MIN -32767

valeur maximale pour un object de type int

INT_MAX +32767

valeur maximale pour un object de type unsigned int

UINT_MAX 65535

valeur minimale pour un object de type long int

LONG_MIN -2147483647

valeur maximale pour un object de type long int

LONG_MAX +2147483647

valeur maximale pour un object de type unsigned long int

ULONG_MAX 4294967295

Si la valeur d’un object de type char sign-extend est utilisée dans une expression, la valeur de CHAR_MIN doit être la même que celle de SCHAR_MIN et la valeur de CHAR_MAX doit être identique à celle de SCHAR_MAX. Si la valeur d’un object de type char ne se prolonge pas lorsqu’il est utilisé dans une expression, la valeur de CHAR_MIN doit être 0 et la valeur de CHAR_MAX doit être identique à celle de UCHAR_MAX ./7/