taille des types de données de base en C

J’ai un exemple de programme que j’ai copié à partir d’un site Web.

int main(void) { int answer; short x = 1; long y = 2; float u = 3.0; double v = 4.4; long double w = 5.54; char c = 'p'; typedef enum { kAtsortingbuteInvalid, kBooleanAtsortingbuteActive, kBooleanAtsortingbuteAlarmSignal, kBooleanAtsortingbuteAlign64, kBooleanAtsortingbuteAutoNegotiationComplete, }codes_t; /* __DATE__, __TIME__, __FILE__, __LINE__ are predefined symbols */ #if 0 printf("Date : %s\n", __DATE__); printf("Time : %s\n", __TIME__); printf("File : %s\n", __FILE__); printf("Line : %d\n", __LINE__); #endif /* The size of various types */ printf("The size of int %zu\n", sizeof(answer)); printf("The size of short %zu\n", sizeof(x)); printf("The size of long %zu\n", sizeof(y)); printf("The size of float %zu\n", sizeof(u)); printf("The size of double %zu\n", sizeof(v)); printf("The size of long double %zu\n", sizeof(w)); printf("The size of char %zu\n", sizeof(c)); printf("The size of enum %zu\n", sizeof(codes_t)); return 0; } 

J’ai exécuté ce programme et le résultat obtenu est le suivant.

 The size of int 4 The size of short 2 The size of long 8 The size of float 4 The size of double 8 The size of long double 16 The size of char 1 The size of enum 4 

J’exécute ceci sur un PC Linux qui exécute Ubuntu 64 bits. Ma question est de savoir si je devrais exécuter le même programme sur une machine 32 bits, puis-je voir des résultats différents? Ou en d’autres termes, la taille des données de base les types dépendent de

  1. processeur
  2. Système opérateur
  3. rien d’autre

Sous réserve de devoir installer certaines bibliothèques [probablement simplement glibc] dans sa variante 32 bits, vous devriez pouvoir essayer vous-même en utilisant gcc -m32 myprog.c [ou clang -m32 myprog.c ].

Cependant, la seule chose répertoriée dans vos éléments qui changera si vous passez d’un système linux x86 64 bits à un système linux x86 32 bits, à l’aide de compilateurs basés sur gcc, est la taille de long . Notez la lourde qualification de x86, gcc, etc. – les compilateurs ont beaucoup de liberté. Quelqu’un pourrait écrire un compilateur pour Linux qui utilise 16 bits int et 64 bits de long sur un système 32 bits sans trop de difficulté. L’utilisation de ce compilateur pour comstackr le kernel Linux et de nombreux outils Linux échouerait probablement [notamment en compilant gcc avec ce compilateur]. Mais vous ne pouvez pas vraiment dire “sur cette architecture” ou “dans ce système d’exploitation” ou “avec ce compilateur” … sans spécifier également quels sont les parameters OTHER.

Exemple: un compilateur Microsoft C / C ++ a une long 32 bits, même sur des systèmes 64 bits. Pourquoi, je vous entends demander? Parce qu’un grand nombre de fonctions de l’API Windows utilisent une valeur long de 32 bits comme inheritance de l’époque où Windows était un système d’exploitation 16 bits sur des processeurs Intel 286/386. Étant donné que (certains des) appels système sont rétrocompatibles avec Windows, le code écrit pour les systèmes 16 bits fonctionnera toujours sous Windows 64 bits [à moins que le code utilise des appels système vraiment inhabituels, et bien sûr , le style aura l’air un peu antique]. Changer long en une valeur de 64 bits aurait cassé une partie de cette fonctionnalité, de sorte que les membres du compilateur de MS ont décidé de s’en tenir à long = 32 bits. Si vous voulez des entiers 64 bits, vous devez utiliser long long ou int64_t ou quelque chose d’autre, pas long . Bien sûr, cela rompt certains codes qui supposent que sizeof(long) == sizeof(void *) . Espérons que la plupart de ces codes ont déjà été corrigés …

Ma question est de savoir si je devrais exécuter le même programme sur une machine 32 bits puis-je voir des résultats différents

Peut être. Ou peut être pas.

Ou en d’autres termes, la taille des types de données de base dépend-elle de 1) le processeur 2) le système d’exploitation 3) toute autre chose?

  1. Oui, 2. oui, 3. oui, par exemple, si vous exécutez une application 32 bits en mode de compatibilité 32 bits sur un système d’exploitation 64 bits, elle utilisera très probablement une taille de mot de 32 bits (bien sûr, elle a été compilé comme ça). Oh, et oui, cela peut aussi dépendre du compilateur.

“Et vos indicateurs de compilateur …” (Merci, Kay!)

Si vous vous souciez de la taille exacte des variables utilisées

 #include  

Et utilisez ensuite les types à largeur fixe définis ici:

 uint8_t uint16_t uint32_t uint64_t 

ou leurs cousins ​​signés

 int8_t int16_t int32_t int64_t 

Ne vous fiez pas à la taille des types natifs en C. Différents compilateurs ont des règles différentes.

Oui, cela dépend du matériel, du système d’exploitation, du compilateur et même de la langue dans certains cas.

Mais sur Linux x86, les longueurs seront de 4 octets sur les plates-formes 32 bits, plutôt que de 8. Les autres, je crois, restnt les mêmes (je ne suis pas sûr du long double).

Anecdote:

J’ai travaillé sur un système 24 bits où la taille des mots était de 24 bits et chaque type natif avait une taille de 1 mot. sizeof (caractère)? 1 (c’est-à-dire: 24 bits). sizeof (int)? 1 (c’est-à-dire: 24 bits). Etc. Amusant!

Les tailles sont définies en pierre par le compilateur au moment de la compilation, car celui-ci doit émettre des instructions spécifiques à la taille, disposer les membres en structures et connaître les tailles de structure pour tous les calculs d’adresse requirejs.

Ainsi, si vous comstackz votre source dans un fichier binary 64 bits et l’exécutez sur plusieurs systèmes différents, les types auront la même taille à chaque exécution, si le système prend en charge le fichier binary.

Si vous comstackz ensuite la source dans un fichier binary 32 bits ou utilisez des commutateurs de compilateur différents, lorsque vous l’exécutez sur un ensemble de systèmes différents, les numéros peuvent être différents de ceux du cas 64 bits, systèmes.