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

Je cherche des informations détaillées concernant la taille des types de base C ++. 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 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 la taille de char , short , int , long , double , float (et d’autres types auxquels je ne pensais pas) sous différentes architectures et compilateurs.

Le standard C ++ ne spécifie pas la taille des types intégraux en octets, mais spécifie les plages minimales qu’ils doivent pouvoir conserver. Vous pouvez déduire la taille minimale en bits de la plage requirejse. Vous pouvez déduire la taille minimale en octets de celle-ci et la valeur de la macro CHAR_BIT qui définit le nombre de bits d’un octet (sur toutes les plates-formes sauf les plus obscures, il s’agit de 8 et ne peut pas être inférieur à 8).

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

Les plages minimales requirejses par la norme (page 22) sont les suivantes:

et plages de types de données sur MSDN :

  1. signed char : de -127 à 127 (notez que de -128 à 127; cela permet d’accommoder les plates-formes à complément à 1 et à signe et à magnitude)
  2. unsigned char : 0 à 255
  3. “plain” char : même intervalle que le caractère signed char ou le caractère 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, tant que

  1. l’expression sizeof(type) * CHAR_BIT évaluée à un nombre de bits suffisamment élevé pour contenir les plages requirejses, et
  2. l’ordre de type est toujours valide (par exemple sizeof(int) <= sizeof(long) ).

Les plages spécifiques à l'implémentation peuvent être trouvées dans l'en-tête dans C, ou dans dans C ++ (ou même mieux, dans le template std::numeric_limits dans l'en-tête ).

Par exemple, voici comment vous trouverez la scope maximale pour int :

C:

 #include  const int min_int = INT_MIN; const int max_int = INT_MAX; 

C ++ :

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

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

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

À une certaine é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 cette norme.

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

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

En pratique, rien de tel. Vous pouvez souvent vous attendre à ce que std::size_t représente la taille entière native non signée de 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 de la version de travail actuelle du dernier standard C ++:

Il existe cinq types d’entiers signés standard: 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.

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, chacun occupant la même quantité de stockage et a les mêmes exigences d’alignement.

Si vous le souhaitez, vous pouvez statiquement (à la compilation) affirmer la taille de ces types fondamentaux. Cela alertera les gens de penser à porter votre code si la taille des hypothèses change.

Il y a standard.

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 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 souhaitez que le nom du type reflète sa taille, vous pouvez consulter l’en-tête , 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.

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

Mis à jour: C ++ 11 a introduit officiellement les types de TR1 dans le standard:

  • long long int
  • non signé long long int

Et les types “dimensionnés” de

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (et les contreparties non signées).

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 existe 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, le cas échéant, est à la mise en œuvre. Il ne doit pas non plus être le plus rapide à toutes fins.

Le standard C ++ le dit ainsi:

3.9.1, §2:

Il existe cinq types entiers signés: “signé char”, “court 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. Plain ints a la taille naturelle suggérée par l’architecture de l’environnement d’exécution (44); les autres types d’entiers signés sont fournis pour répondre à des besoins spéciaux.

(44) c’est-à-dire suffisamment grand pour contenir n’importe quelle valeur dans l’intervalle INT_MIN et INT_MAX, comme défini dans l’en-tête .

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

Non, il n’y a pas de norme pour les tailles de type. Standard exige uniquement que:

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

La meilleure chose à faire si vous voulez des variables de taille fixe 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 moyen le plus portable .

Nous sums 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; ... 

Donc, lorsque nous transférons le code sur une autre machine où la taille de long int est en fait de 4, nous pouvons simplement redéfinir l’occurrence unique de int.

 typedef long int int32; int32 i; int32 j; ... 

Pour les nombres à virgule flottante, il existe un standard (IEEE754) : les flottants sont 32 bits et les doubles 64. Il s’agit d’une norme matérielle et non d’un standard C ++, donc les compilateurs pourraient théoriquement définir float et doubler Nous n’avons jamais vu une architecture qui utilise quelque chose de différent.

Il existe une norme et celle-ci est spécifiée dans les divers documents de normes (ISO, ANSI et autres).

Wikipédia a une excellente page expliquant les différents types et le maximum qu’ils peuvent stocker: Integer in Computer Science.

Cependant, même avec un compilateur C ++ standard, vous pouvez vous en procurer relativement facilement en utilisant l’extrait de code suivant:

 #include  #include  int main() { // Change the template parameter to the various different types. std::cout << std::numeric_limits::max() << std::endl; } 

La documentation de std :: numeric_limits est disponible sur Roguewave . Il comprend une pléthore d'autres commandes que vous pouvez appeler pour connaître les différentes limites. Cela peut être utilisé avec n'importe quel type arbitraire qui transmet la taille, par exemple std :: streamsize.

La réponse de John contient la meilleure description, car celles-ci sont garanties. Quelle que soit la plate-forme sur laquelle vous vous trouvez, il existe une autre page qui explique plus en détail le nombre de bits que chaque type DOIT contenir: int types , définis dans la norme.

J'espère que ça aide!

1) Tableau N1 dans l’article ” Les problèmes oubliés du développement de programmes 64 bits ”

2) ” Modèle de données ”

Vous pouvez utiliser:

 cout << "size of datatype = " << sizeof(datatype) << endl; 

datatype = int , long int etc. Vous pourrez voir la taille de n'importe quel type de données que vous tapez.

Lorsqu’il s’agit de types intégrés pour différentes architectures et différents compilateurs, exécutez simplement le code suivant sur votre architecture avec votre compilateur pour voir ce qu’il génère. Ci-dessous, ma sortie Ubuntu 13.04 (Raring Ringtail) 64 bits g ++ 4.7.3. Veuillez également noter ce qui a été répondu ci-dessous, c’est pourquoi le résultat est ordonné comme tel:

“Il existe cinq types entiers signés standard: 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.”

 #include  int main ( int argc, char * argv[] ) { std::cout<< "size of char: " << sizeof (char) << std::endl; std::cout<< "size of short: " << sizeof (short) << std::endl; std::cout<< "size of int: " << sizeof (int) << std::endl; std::cout<< "size of long: " << sizeof (long) << std::endl; std::cout<< "size of long long: " << sizeof (long long) << std::endl; std::cout<< "size of float: " << sizeof (float) << std::endl; std::cout<< "size of double: " << sizeof (double) << std::endl; std::cout<< "size of pointer: " << sizeof (int *) << std::endl; } size of char: 1 size of short: 2 size of int: 4 size of long: 8 size of long long: 8 size of float: 4 size of double: 8 size of pointer: 8 

Comme mentionné, la taille doit refléter l’architecture actuelle. Vous pourriez prendre un maximum dans limits.h si vous voulez voir comment votre compilateur actuel gère les choses.

Comme d’autres ont répondu, les “standards” laissent la plupart des détails comme “implementation defined” et indiquent seulement que le type “char” est au moins “char_bis” wide, et que “char <= short <= int <= long < = long long "(float et double sont assez cohérents avec les normes IEEE en virgule flottante, et long double est généralement identique au double - mais peut être plus important avec des implémentations plus actuelles).

Une des raisons de ne pas avoir de valeurs très précises et précises est que les langages comme C / C ++ ont été conçus pour être portables sur un grand nombre de plates-formes matérielles – Y compris les systèmes informatiques dont la taille peut être 4 bits ou 7 bits, voire une valeur autre que les ordinateurs “8/16/32/64 bits” auxquels l’utilisateur d’ordinateur domestique moyen est exposé. (La taille des mots signifie ici combien de bits le système fonctionne normalement – Encore une fois, ce n’est pas toujours le cas avec les ordinateurs à 8 bits)

Si vous avez vraiment besoin d’un object (au sens d’une série de bits représentant une valeur intégrale) d’un nombre spécifique de bits, la plupart des compilateurs ont une méthode pour le spécifier; Mais ce n’est généralement pas portable, même entre les compilateurs fabriqués par la société AME mais pour des plates-formes différentes. Certaines normes et pratiques (en particulier limitations.h et autres) sont suffisamment courantes pour que la plupart des compilateurs prennent en charge la détermination du type le mieux adapté à une plage de valeurs spécifique, mais pas au nombre de bits utilisés. (Autrement dit, si vous savez que vous devez contenir des valeurs comsockets entre 0 et 127, vous pouvez déterminer que votre compilateur prend en charge un type de 8 bits “int8” suffisamment important pour contenir toute la plage souhaitée, mais pas “int7” type qui correspondrait exactement à 7 bits.)

Remarque: de nombreux paquets source Un * x ont utilisé un script “./configure” qui parsingra les capacités du compilateur / système et produira un fichier Makefile approprié et config.h. Vous pouvez examiner certains de ces scripts pour voir comment ils fonctionnent et comment ils parsingnt les fonctionnalités du système de compilation / compilation et suivent leur exemple.

Si vous vous intéressez à une solution C ++ pure, j’ai utilisé des modèles et uniquement du code standard C ++ pour définir les types au moment de la compilation en fonction de leur taille de bit. Cela rend la solution portable entre les compilateurs.

L’idée est très simple: créez une liste contenant les types char, int, short, long, long long (versions signées et non signées) et scan the list et, à l’aide du modèle numeric_limits, sélectionnez le type avec une taille donnée.

Y compris cet en-tête vous avez 8 type stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.

Si un type ne peut pas être représenté, il sera évalué à stdtype :: null_type également déclaré dans cet en-tête.

LE CODE CI-DESSOUS EST DONNÉ SANS GARANTIE, VEUILLEZ LE DOUBLER.
JE SUIS NOUVEAU À METAPROGRAMMING TOO, N’HÉSITEZ PAS À MODIFIER ET À CORRIGER CE CODE.
Testé avec DevC ++ (donc une version gcc autour de 3.5)

 #include  namespace stdtype { using namespace std; /* * THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE. * YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS * DECLARED/USED. * * PLEASE NOTE that C++ std define sizeof of an empty class to be 1. */ class null_type{}; /* * Template for creating lists of types * * T is type to hold * S is the next type_list type * * Example: * Creating a list with type int and char: * typedef type_list > test; * test::value //int * test::next::value //char */ template  struct type_list { typedef T value; typedef S next; }; /* * Declaration of template struct for selecting a type from the list */ template  struct select_type; /* * Find a type with specified "b" bit in list "list" * * */ template  struct find_type { private: //Handy name for the type at the head of the list typedef typename list::value cur_type; //Number of bits of the type at the head //CHANGE THIS (comstack time) exp TO USE ANOTHER TYPE LEN COMPUTING enum {cur_type_bits = numeric_limits::digits}; public: //Select the type at the head if b == cur_type_bits else //select_type call find_type with list::next typedef typename select_type::type type; }; /* * This is the specialization for empty list, return the null_type * OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case * (ie search for type with 17 bits on common archs) */ template  struct find_type { typedef null_type type; }; /* * Primary template for selecting the type at the head of the list if * it matches the requested bits (b == ctl) * * If b == ctl the partial specified templated is evaluated so here we have * b != ctl. We call find_type on the next element of the list */ template  struct select_type { typedef typename find_type::type type; }; /* * This partial specified templated is used to select top type of a list * it is called by find_type with the list of value (consumed at each call) * the bits requested (b) and the current type (top type) length in bits * * We specialice the b == ctl case */ template  struct select_type { typedef typename list::value type; }; /* * These are the types list, to avoid possible ambiguity (some weird archs) * we kept signed and unsigned separated */ #define UNSIGNED_TYPES type_list > > > > #define SIGNED_TYPES type_list > > > > /* * These are acutally typedef used in programs. * * Nomenclature is [u]intN where u if present means unsigned, N is the * number of bits in the integer * * find_type is used simply by giving first a type_list then the number of * bits to search for. * * NB. Each type in the type list must had specified the template * numeric_limits as it is used to compute the type len in (binary) digit. */ typedef find_type::type uint8; typedef find_type::type uint16; typedef find_type::type uint32; typedef find_type::type uint64; typedef find_type::type int8; typedef find_type::type int16; typedef find_type::type int32; typedef find_type::type int64; } 
 unsigned char bits = sizeof(X) << 3; 

X est un caractère, int , long etc. vous donnera la taille de X en bits.

From Alex B Le standard C ++ ne spécifie pas la taille des types intégraux 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 requirejse. Vous pouvez déduire la taille minimale en octets de celle-ci et la valeur de la macro CHAR_BIT qui définit le nombre de bits d’un octet (sur toutes les plates-formes sauf les plus obscures, il s’agit de 8 et ne peut pas être inférieur à 8).

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

Les plages minimales requirejses par la norme (page 22) sont les suivantes:

et plages de types de données sur MSDN:

caractère signé: -127 à 127 (notez -128 à 127; ceci permet d’utiliser des plates-formes complémentaires) char sans signe: 0 à 255 char “plain”: -127 à 127 ou 0 à 255 (dépend du caractère signé par défaut) signé short: -32767 à 32767 non signé short: 0 à 65535 signé int: -32767 à 32767 unsigned int: 0 à 65535 signé long: -2147483647 à 2147483647 unsigned long: 0 à 4294967295 signé long long: -9223372036854775807 à 9223372036854775807 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

l’expression sizeof (type) * CHAR_BIT évalue le nombre de bits suffisant pour contenir les plages requirejses, et le classement de type est toujours valide (par exemple sizeof (int) <= sizeof (long)). Les plages spécifiques à l'implémentation peuvent être trouvées dans l'en-tête de C, ou dans C ++ (ou même mieux, std :: numeric_limits dans l'en-tête).

Par exemple, voici comment vous trouverez la scope maximale pour int:

C:

 #include  const int min_int = INT_MIN; const int max_int = INT_MAX; 

C ++:

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

Ceci est correct, cependant, vous avez également raison de dire que: char: 1 octet court: 2 octets int: 4 octets long: 4 octets flottant: 4 octets double: 8 octets

Étant donné que les architectures 32 bits sont toujours les architectures les plus utilisées et les plus utilisées, et qu’elles ont conservé ces tailles standard avant 32 bits lorsque la mémoire était moins disponible et pour assurer la compatibilité et la normalisation, elles sont restées les mêmes. Même les systèmes 64 bits ont tendance à les utiliser et ont des extensions / modifications. Veuillez faire référence à ceci pour plus d’informations:

http://fr.cppreference.com/w/cpp/language/types

Je remarque que toutes les autres réponses se sont concentrées presque exclusivement sur les types intégraux, tandis que l’interrogateur a également posé des questions sur les points flottants.

Je ne pense pas que la norme C ++ l’exige, mais les compilateurs pour les plates-formes les plus courantes de nos jours suivent généralement la norme IEEE754 pour leurs nombres à virgule flottante. Cette norme spécifie quatre types de virgule flottante binary (ainsi que certains formats BCD, pour lesquels je n’ai jamais vu de support dans les compilateurs C ++):

  • Demi-précision (binary16) – Signification 11 bits, gamme d’exposant -14 à 15
  • Précision simple (binary32) – Sensibilité sur 24 bits, plage d’exposant de -126 à 127
  • Double précision (binary64) – signification de 53 bits, plage d’exposant de -1022 à 1023
  • Précision quadruple (binary128) – signification de 113 bits, plage d’exposant de -16382 à 16383

Comment est-ce que cela correspond aux types C ++, alors? Généralement, le float utilise une précision unique; Ainsi, sizeof(float) = 4 . Alors double utilise la double précision (je crois que c’est la source du nom double ), et le long double peut avoir une précision double ou quadruple (il est quadruple sur mon système, mais sur les systèmes 32 bits il peut être double). I don’t know of any comstackrs that offer half precision floating-points.

In summary, this is the usual:

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 or 16

As you mentioned – it largely depends upon the comstackr and the platform. For this, check the ANSI standard, http://home.att.net/~jackklein/c/inttypes.html

Here is the one for the Microsoft comstackr: Data Type Ranges .

You can use variables provided by libraries such as OpenGL , Qt , etc.

For example, Qt provides qint8 (guaranteed to be 8-bit on all platforms supported by Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.

On a 64-bit machine:

 int: 4 long: 8 long long: 8 void*: 8 size_t: 8 

There are four types of integers based on size:

  • short integer: 2 byte
  • long integer: 4 byte
  • long long integer: 8 byte
  • integer: depends upon the comstackr (16 bit, 32 bit, or 64 bit)