753 votes

Selon la norme C++, quelle doit être la taille des types int et long ?

Je cherche des informations détaillées concernant la taille des types C++ de base. Je sais que cela dépend de l'architecture (16 bits, 32 bits, 64 bits) et du compilateur.

Mais existe-t-il des normes pour le C++ ?

J'utilise Visual Studio 2008 sur une architecture 32 bits. Voici ce que j'obtiens :

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

J'ai essayé de trouver, sans grand succès, des informations fiables sur les tailles des produits de l'UE. char , short , int , long , double , float (et d'autres types auxquels je n'ai pas pensé) sous différentes architectures et compilateurs.

23 votes

@thyrgle ce n'est pas par choix... il y a tellement d'architectures à supporter qu'il faut être flexible.

6 votes

6 votes

Pourquoi ne pas supprimer tous les types vagues et normaliser le tout avec des types de longueur de bit définis, par exemple int32_t, uint32_t, int64_t, etc.

740voto

Alex B Points 34304

La norme C++ ne précise pas la taille des types intégraux en octets, mais elle spécifie les plages minimales qu'ils doivent pouvoir contenir. Vous pouvez déduire la taille minimale en bits à partir de la plage requise. Vous pouvez déduire la taille minimale en octets à partir de cette plage et de la valeur de l'attribut CHAR_BIT macro qui définit le nombre de bits dans un octet . Dans toutes les plateformes, sauf les plus obscures, c'est 8, et ça ne peut pas être moins que 8.

Une contrainte supplémentaire pour char est que sa taille est toujours de 1 octet, soit CHAR_BIT bits (d'où le nom). Cela est indiqué explicitement dans la norme.

La norme C est une référence normative pour la norme C++. Ainsi, même s'il n'énonce pas ces exigences de manière explicite, le C++ exige des plages minimales requis par la norme C (page 22), qui sont les mêmes que ceux de Data Type Ranges sur MSDN :

  1. signed char -127 à 127 (attention, pas -128 à 127 ; cela correspond aux plateformes de complément à 1 et de signe et magnitude)
  2. unsigned char : 0 à 255
  3. "simple" char : même gamme que signed char o unsigned char , définie par la mise en œuvre
  4. signed short : -32767 à 32767
  5. unsigned short : 0 à 65535
  6. signed int : -32767 à 32767
  7. unsigned int : 0 à 65535
  8. signed long : -2147483647 à 2147483647
  9. unsigned long : 0 à 4294967295
  10. signed long long : -9223372036854775807 à 9223372036854775807
  11. unsigned long long : 0 à 18446744073709551615

Une implémentation C++ (ou C) peut définir la taille d'un type en octets. sizeof(type) à n'importe quelle valeur, tant que

  1. l'expression sizeof(type) * CHAR_BIT est évalué à un nombre de bits suffisamment élevé pour contenir les plages requises, et
  2. l'ordre des types est toujours valable (par ex. sizeof(int) <= sizeof(long) ).

En mettant tout cela ensemble, nous sommes assurés que :

  • char , signed char et unsigned char sont au moins de 8 bits
  • signed short , unsigned short , signed int et unsigned int sont au moins de 16 bits
  • signed long et unsigned long sont au moins de 32 bits
  • signed long long et unsigned long long sont au moins de 64 bits

Aucune garantie n'est donnée quant à la taille des float o double sauf que double fournit au moins autant de précision que float .

Les plages spécifiques à l'implémentation peuvent être trouvées dans <limits.h> en C, ou <climits> en C++ (ou encore mieux, des modèles std::numeric_limits sur <limits> en-tête).

Par exemple, c'est ainsi que vous trouverez la portée maximale pour int :

C :

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

C++ :

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

55 votes

Au contraire, la norme C++ utilise le mot octet pour signifier "1 char ", et non le sens habituel.

0 votes

Il serait bien que cette réponse soit mise à jour avec les gammes C++11, qui, je pense, ont changé (je n'en suis pas sûr).

1 votes

@gsingh2011 Je ne pense pas que les plages aient changé, bien que des types précis de C99 inttypes.h aient été ajoutés (par exemple int64_t), mais il est facile d'en déterminer la taille.

278voto

Jonathan Leffler Points 299946

Pour les systèmes 32 bits, la norme "de facto" est ILP32, c'est-à-dire.., int , long et le pointeur sont tous des quantités de 32 bits.

Pour les systèmes 64 bits, la principale norme Unix "de facto" est LP64. long et le pointeur sont 64 bits (mais int est de 32 bits). La norme Windows 64 bits est LLP64 - long long et le pointeur sont 64 bits (mais long et int sont toutes deux 32 bits).

À une époque, certains systèmes Unix utilisaient une organisation ILP64.

Aucune de ces normes de facto n'est légiférée par la norme C (ISO/IEC 9899:1999), mais toutes sont autorisées par celle-ci.

Et, par définition, sizeof(char) est 1 nonobstant le test dans la configuration Perl script.

Notez qu'il y avait des machines (Crays) où CHAR_BIT était beaucoup plus grande que 8. Cela signifie, IIRC, que sizeof(int) était également 1, car les deux char et int étaient de 32 bits.

86 votes

+1 pour avoir dit comment les choses sont réellement dans les cas qui comptent le plus, plutôt que comment les choses sont en théorie. Si vous voulez 32 bits, utilisez int, si vous voulez 64 bits, utilisez long long. Si vous voulez du natif, utilisez size_t. Évitez le long "ordinaire" car il varie. Cela devrait fonctionner pour la plupart des applications.

52 votes

+1 pour la réponse. @Eloff : au contraire... si vous voulez du 32 bit utilisez [u]int32_t ou similaire, si vous voulez du 64 bits, utilisez [u]int64_t ... si vous n'avez pas d'en-tête pour eux, téléchargez ou faites-en un, de préférence avec une sélection de ces types au moment de la compilation ou des assertions statiques pour vérifier la taille. pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html Si les tailles précises ne sont pas si importantes et que vous vous souciez seulement qu'elles soient au moins de cette taille, alors votre conseil vaut pour les plateformes PC/serveur modernes courantes.

11 votes

Notez que les vieilles machines Cray ne sont pas les seules à avoir un CHAR_BIT > 8. Par exemple, les DSP ont souvent un CHAR_BIT de 16 ou 32. (voir par exemple ces )

92voto

John Leidegren Points 21951

Dans la pratique, cela n'existe pas. Souvent, vous pouvez vous attendre std::size_t pour représenter la taille des entiers natifs non signés sur l'architecture actuelle, c'est-à-dire 16 bits, 32 bits ou 64 bits, mais ce n'est pas toujours le cas, comme indiqué dans les commentaires de cette réponse.

En ce qui concerne tous les autres types intégrés, cela dépend vraiment du compilateur. Voici deux extraits tirés du projet de travail actuel de la dernière norme C++ :

Il existe cinq types d'entiers signés standard : signed char, short int, int, long int et long long int. Dans cette liste, chaque type fournit au moins autant de stockage que ceux qui le précèdent dans la liste.

Pour chacun des types d'entiers signés standard, il existe un type d'entier non signé standard correspondant (mais différent) : unsigned char, unsigned short int, unsigned int, unsigned long int et unsigned long long int, chacun occupant la même quantité de mémoire et ayant les mêmes exigences d'alignement.

Si vous le souhaitez, vous pouvez affirmer statiquement (à la compilation) la taille de ces types fondamentaux. Cela alertera les gens pour qu'ils réfléchissent au portage de votre code si les hypothèses sizeof changent.

7 votes

Bon post. une autre chose qui est requise est la taille minimale des bits suivants (documentée dans c89 / c99 avec limits.h et reprise par c++) : char >=8, short et int >=16, long >=32 .

2 votes

De plus, sur une plateforme AVR 8 bits, size_t ne sera pas de 8 bits, mais de 16, car les tailles des pointeurs et des int sont de 16 bits. Ainsi, la taille native des données du processeur n'est pas liée à size_t.

86voto

yinyueyouge Points 1192

Il y a une norme.

La norme C90 exige que

sizeof(short) <= sizeof(int) <= sizeof(long)

La norme C99 exige que

sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

Voici les spécifications du C99 . La page 22 détaille les tailles des différents types d'intégrateurs.

Voici les tailles des types d'int (bits) pour les plateformes Windows :

Type           C99 Minimum     Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

Si vous êtes concerné par la portabilité, ou si vous voulez que le nom du type reflète la taille, vous pouvez regarder l'en-tête <inttypes.h> où les macros suivantes sont disponibles :

int8_t
int16_t
int32_t
int64_t

int8_t est garanti comme étant de 8 bits, et int16_t est garanti comme étant de 16 bits, etc.

10 votes

Petit détail : où la norme dit-elle que sizeof(long) < sizeof(long long) par opposition à la symétrique sizeof(long) <= sizeof(long long) ?

3 votes

@JonathonLeffler - voir C99 5.2.4.2.1 - Sizes of integer types. minsizeof(int)==16-bits, minsizeof(long)==32-bits, minsizeof(long long)==64-bits. Donc je pense que vous avez raison sur le <= car aucun maxsizeof(type) n'est spécifié.

2 votes

De même, sizeof(float) <= sizeof(double) <= sizeof(long double). Selon la norme C99 7.12, paragraphe 2.

39voto

Ben Points 3042

Si vous avez besoin de types de taille fixe, utilisez des types comme uint32_t (unsigned integer 32 bits) définis dans le document stdint.h . Ils sont spécifiés dans C99 .

10 votes

Ils sont spécifiés mais pas obligatoires.

2 votes

@dreamlax Quelles sont les plateformes qui ne l'incluent pas ?

3 votes

@LeviMorrison : Toute plateforme qui ne les a pas dans la forme requise. Une plateforme qui a CHAR_BIT == 16 par exemple, n'aura pas int8_t . Toute plateforme n'utilisant pas le complément à deux n'aura pas tout d'entre eux (le complément à deux étant requis par la norme).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X