Question Qu'est-ce que le standard C ++ indique la taille de int, long type à être?


Je suis à la recherche d'informations détaillées sur 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 standards pour C ++?

J'utilise Visual Studio 2008 sur une architecture 32 bits. Voici ce que je reçois:

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 indiquant les tailles de char, short, int, long, double, float (et d'autres types auxquels je n'ai pas pensé) sous différentes architectures et compilateurs.


628
2018-02-26 07:59


origine


Réponses:


La norme C ++ ne spécifie pas la taille des types entiers en octets, mais spécifie les plages minimales qu'ils doivent pouvoir contenir. Vous pouvez déduire la taille minimale en bits de la plage requise. Vous pouvez déduire la taille minimale en octets de cela et la valeur de la CHAR_BIT macro que définit le nombre de bits dans un octet (Dans toutes les plates-formes, sauf les plus obscures, il est 8, et il ne peut pas être inférieur à 8).

Une contrainte supplémentaire pour char est que sa taille est toujours 1 octet, ou CHAR_BIT bits (d'où le nom).

Gammes minimales requis par la norme (page 22) sont:

et types de données sur MSDN:

  1. signed char: -127 à 127 (notez, pas -128 à 127, ceci s'adapte aux plates-formes de complément et de taille de signe)
  2. unsigned char: 0 à 255
  3. "plaine" char: même plage que signed char ou unsigned char, défini par l'implémentation
  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, aussi longtemps que

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

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

Par exemple, voici comment vous trouverez la gamme 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();

635
2018-02-26 08:47



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

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

À un moment donné, 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 / CEI 9899: 1999), mais toutes sont autorisées par elle.

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

Notez qu'il y avait des machines (Crays) où CHAR_BIT était beaucoup plus grand que 8. Cela signifiait, IIRC, que sizeof(int) était aussi 1, parce que les deux char et int étaient 32 bits.


209
2018-02-26 08:47



En pratique, il n'y a pas de telle chose. Souvent, vous pouvez vous attendre std::size_tpour représenter la taille entière native non signée 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.

Dans la mesure où tous les autres types intégrés vont, cela dépend vraiment du compilateur. Voici deux extraits du brouillon actuel du dernier standard C ++:

Il existe cinq types entiers signés standards: char signé, int court, 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 entiers signés standards, il existe un type entier non signé standard correspondant (mais différent): unsigned char, unsigned court int, unsigned int, unsigned long int, et unsigned long long int, chacun occupant la même quantité de stockage et a les mêmes exigences d'alignement.

Si vous voulez vous pouvez statiquement (compiler-time) affirmer la taille de ces types fondamentaux. Cela alertera les gens de penser à porter votre code si la taille des hypothèses change.


80
2018-02-26 08:02



Il y a la norme.

La norme C90 exige que

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

Norme C99 exige que

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

Voici la spécification C99. Page 22 détails tailles de différents types intégraux.

Voici les tailles de type int (bits) pour les plates-formes 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 à 8 bits, et int16_t est garanti à 16 bits, etc.


77
2018-03-30 14:49



Si vous avez besoin de types de taille fixes, utilisez des types comme uint32_t (entier non signé 32 bits) défini dans stdint.h. Ils sont spécifiés dans C99.


38
2018-02-26 08:18



Mise à jour: C ++ 11 a officiellement introduit les types de TR1 dans la norme:

  • long long int
  • non signé long long int

Et les types "taille" de <cstdint>

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (et les homologues non signés).

De plus, vous obtenez:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • Plus les homologues non signés.

Ces types représentent les plus petits types entiers avec au moins le nombre de bits spécifié. De même, il y a les types entiers "les plus rapides" avec au moins le nombre de bits spécifié:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • Plus les versions non signées.

Qu'est-ce que «rapide» signifie, si quelque chose, est à la mise en œuvre. Il n'a pas besoin d'être le plus rapide à toutes fins.


32
2018-02-26 19:32



le Norme C ++ dit comme ça:

3.9.1, §2:

Il existe cinq types entiers signés:   "char signé", "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. Les ints simples ont le   taille naturelle suggérée par le   architecture de l'exécution   environnement (44); l'autre signé   types entiers sont fournis pour répondre   besoins spéciaux.

(44) c'est-à-dire assez grand pour contenir   toute valeur dans la plage de INT_MIN et   INT_MAX, tel que défini dans l'en-tête    <climits>.

La conclusion: Cela dépend de l'architecture sur laquelle vous travaillez. Toute autre hypothèse est fausse.


17
2017-09-01 13:41



Non, il n'y a pas de norme pour les tailles de caractères. La norme exige seulement que:

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

La meilleure chose que vous pouvez faire si vous voulez des variables de tailles fixes est d'utiliser des macros comme ceci:

#ifdef SYSTEM_X
  #define WORD int
#else
  #define WORD long int
#endif

Ensuite, vous pouvez utiliser WORD pour définir vos variables. Ce n'est pas que j'aime ça mais c'est le le plus portable façon.


12
2018-02-26 08:07



Nous sommes autorisés à définir un synonyme pour le type afin que nous puissions créer notre propre "standard".

Sur une machine dans laquelle sizeof (int) == 4, on peut définir:

typedef int int32;

int32 i;
int32 j;
...

Ainsi, lorsque nous transférons le code sur une machine différente où la taille de long int est 4, nous pouvons simplement redéfinir l'occurrence unique de int.

typedef long int int32;

int32 i;
int32 j;
...

9
2017-07-14 16:01



Pour les nombres flottants il y a une norme (IEEE754): les flotteurs ont 32 bits et les doubles 64. C'est un standard matériel, pas un standard C ++, donc les compilateurs pourraient théoriquement définir float et doubler à une autre taille, mais en pratique je n'ai jamais vu une architecture qui utilise quelque chose de différent.


8
2018-02-26 08:49