Différence entre int32, int, int32_t, int8 et int8_t

104

Je suis tombé sur le type de données int32_tdans un programme C récemment. Je sais qu'il stocke 32 bits, mais ne le faites pas intet int32faites de même?

Aussi, je souhaite utiliser chardans un programme. Puis-je utiliser à la int8_tplace? Quelle est la différence?

Pour résumer: quelle est la différence entre int32, int, int32_t, int8 et int8_t en C?

linuxfreak
la source

Réponses:

122

Entre int32et int32_t, (et de même entre int8et int8_t) la différence est assez simple: le standard C définit int8_tet int32_t, mais ne définit rien de nommé int8ou int32- ce dernier (s'il existe du tout) provient probablement d'un autre en-tête ou d'une bibliothèque (très probablement est antérieure à l'ajout de int8_tet int32_tdans C99).

Plain intest assez différent des autres. Où int8_tet int32_tchacun ont une taille spécifiée, intpeut être n'importe quelle taille> = 16 bits. À des moments différents, 16 bits et 32 ​​bits ont été raisonnablement courants (et pour une implémentation 64 bits, il devrait probablement s'agir de 64 bits).

D'autre part, il intest garanti d'être présent dans chaque implémentation de C, où int8_tet int32_tnon. Il est probablement possible de se demander si cela compte pour vous. Si vous utilisez C sur de petits systèmes embarqués et / ou des compilateurs plus anciens, cela peut être un problème. Si vous l'utilisez principalement avec un compilateur moderne sur des ordinateurs de bureau / serveur, ce ne sera probablement pas le cas.

Oups - j'ai manqué la partie à propos de char. Vous utiliseriez à la int8_tplace de char si (et seulement si) vous voulez qu'un type entier soit garanti exactement 8 bits. Si vous souhaitez stocker des caractères, vous souhaiterez probablement utiliser à la charplace. Sa taille peut varier (en termes de nombre de bits) mais elle est garantie d'être exactement un octet. Une petite bizarrerie cependant: il n'y a aucune garantie quant à savoir si un plain charest signé ou non (et de nombreux compilateurs peuvent en faire l'un ou l'autre, en fonction d'un indicateur de compilation). Si vous devez vous assurer qu'il est signé ou non signé, vous devez le spécifier explicitement.

Jerry Coffin
la source
1
@linuxfreak: Je ne sais pas bool_t- je n'en ai jamais entendu parler auparavant. La norme C définit _Boolcomme un type intégré. boolest défini uniquement si vous #include <stdbool.h>(comme une macro qui se développe _Bool).
Jerry Coffin
5
Vous avez dit "pour une implémentation 64 bits, (int) devrait probablement être 64 bits". En pratique, int est 32 bits sur toutes les plates-formes 64 bits courantes, notamment Windows, Mac OS X, Linux et diverses versions d'UNIX. Une exception est Cray / UNICOS mais ils sont démodés de nos jours.
Sam Watkins
6
@SamWatkins: Oui, c'est pourquoi j'ai soigneusement dit "devrait être", pas "est". La norme dit que c'est "la taille naturelle suggérée par l'architecture", ce qui (IMO) signifie que sur un processeur 64 bits, il devrait vraiment être 64 bits (même si, pour le meilleur ou pour le pire, vous avez tout à fait raison de dire que ce n'est généralement pas le cas. t). D'un point de vue plus pratique, il est extrêmement pratique d'avoir un type 32 bits parmi les types de C89, et si int vaut 64 bits, long doit également être au moins 64 bits, il n'y aura donc souvent pas de 32 bits type.
Jerry Coffin
2
@barlop: Oui. (C et C ++ imposent tous deux une plage minimale de 255 valeurs pour char, il nécessite donc au moins 8 bits, mais peut être plus).
Jerry Coffin
2
J'ai toujours eu l'impression qu'un octet était exactement 8 bits, pas n'importe où à partir de 8 bits
ErlVolton
18

Les types de données _t sont des types typedef dans l'en-tête stdint.h, tandis que int est un type de données fondamental intégré. Cela rend le _t disponible uniquement si stdint.h existe. int, d'autre part, est garanti d'exister.

Superman
la source
1
Pourquoi utiliserait-on les _t?
Deven
@Deven Pour éviter le cas où votre code fonctionne quelque part mais pas ailleurs.
Franklin Yu
2

Gardez toujours à l'esprit que 'size' est variable si elle n'est pas explicitement spécifiée, donc si vous déclarez

 int i = 10;

Sur certains systèmes, cela peut entraîner un entier de 16 bits par le compilateur et sur d'autres, il peut en résulter un entier de 32 bits (ou un entier de 64 bits sur les systèmes plus récents).

Dans les environnements embarqués, cela peut aboutir à des résultats étranges (en particulier lors de la gestion des E / S mappées en mémoire ou peut être considéré comme une situation de tableau simple), il est donc fortement recommandé de spécifier des variables de taille fixe. Dans les anciens systèmes, vous pouvez rencontrer

 typedef short INT16;
 typedef int INT32;
 typedef long INT64; 

À partir de C99, les concepteurs ont ajouté le fichier d'en-tête stdint.h qui exploite essentiellement des typedefs similaires.

Sur un système basé sur Windows, vous pouvez voir des entrées dans le fichier d'en-tête stdin.h comme

 typedef signed char       int8_t;
 typedef signed short      int16_t;
 typedef signed int        int32_t;
 typedef unsigned char     uint8_t;

Il y a beaucoup plus à cela, comme les types d'entiers de largeur minimale ou de largeur exacte, je pense que ce n'est pas une mauvaise chose d'explorer stdint.h pour une meilleure compréhension.

Naumann
la source
1
Votre code a une faute de frappe:, typedef short INT16;non typedefs short INT16.
Galaxy du