Il est en fait assez courant de stocker un nombre sans avoir besoin de connaître la taille exacte du type. Il y a beaucoup de quantités dans mes programmes que je peux raisonnablement supposer ne dépasseront pas 2 milliards, ou contraindre à ne pas le faire. Mais cela ne signifie pas que j'ai besoin d'un type exact de 32 bits pour les stocker, tout type pouvant aller jusqu'à au moins 2 milliards me convient.
Si vous essayez d'écrire un code très portable, vous devez garder à l'esprit que les types de largeur fixe sont tous optionnels.
Sur une implémentation C99 où CHAR_BIT
est supérieur à 8
, il n'y a pas de int8_t
. La norme l'interdit d'exister car il aurait des bits de remplissage, et les types intN_t
sont définis sans bits de remplissage (7.18.1.1/1). uint8_t
est donc également interdit parce qu'une implémentation n'est pas autorisée à définir uint8_t
sans int8_t
.
Ainsi, dans un code très portable, si vous avez besoin d'un type signé capable de contenir des valeurs jusqu'à 127, vous devriez utiliser l'un des signed char
, int
, int_least8_t
ou int_fast8_t
selon que vous voulez demander au compilateur de le rendre :
- fonctionner en C89 (
signed char
ou int
)
- éviter des promotions d'entiers surprenantes dans les expressions arithmétiques (
int
)
- petit (
int_least8_t
ou signed char
)
- rapide (
int_fast8_t
ou int
)
Il en va de même pour un type non signé jusqu'à 255, avec unsigned char
, unsigned int
, uint_least8_t
et uint_fast8_t
.
Si vous avez besoin d'arithmétique modulo-256 dans un code très portable, vous pouvez soit prendre le modulo vous-même, masquer des bits, ou jouer avec des champs de bits.
En pratique, la plupart des gens n'ont jamais besoin d'écrire du code aussi portable. Pour le moment, CHAR_BIT > 8
ne se produit que sur un matériel spécialisé, et votre code pour un usage général ne sera pas utilisé sur celui-ci. Bien sûr, cela pourrait changer à l'avenir, mais s'il le fait, je soupçonne qu'il y a tellement de code qui fait des hypothèses sur Posix et/ou Windows (qui garantissent que CHAR_BIT == 8
), que gérer la non-portabilité de votre code sera une petite partie d'un grand effort pour porter du code vers cette nouvelle plate-forme. Toute implémentation de ce genre devra probablement se soucier de comment se connecter à l'internet (qui fonctionne en octets), bien avant de s'inquiéter de comment faire fonctionner votre code :-)
Si vous supposez de toute façon que CHAR_BIT == 8
, je ne pense pas qu'il y ait de raison particulière d'éviter (u)int8_t
sauf si vous voulez que le code fonctionne en C89. Même en C89, il n'est pas si difficile de trouver ou d'écrire une version de stdint.h
pour une implémentation particulière. Mais si vous pouvez facilement écrire votre code pour ne nécessiter que le type puisse contenir 255
, plutôt que d'exiger qu'il ne puisse pas contenir 256
, alors vous feriez mieux d'éviter la dépendance de CHAR_BIT == 8
.