Je recherche des informations détaillées sur 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 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 beaucoup de succès, des informations fiables indiquant les dimensions de char
, short
, int
, long
, double
, float
(et d' autres types , je ne pense pas que des) sous différentes architectures et compilateurs.
int16_t
,int32_t
etint64_t
(besoin de l'iostream
inclure pour cela si je me souviens bien). Ce qui est bien à ce sujet, c'est que int64_t ne devrait pas avoir de problèmes sur un système 32 bits (cela aura un impact sur les performances).<cstdint>
, non<iostream>
.Réponses:
La norme C ++ ne spécifie 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 de la plage requise. Vous pouvez en déduire la taille minimale en octets et la valeur de la
CHAR_BIT
macro qui définit le nombre de bits dans un octet . Dans toutes les plates-formes, sauf les plus obscures, il s'agit de 8, et il ne peut pas être inférieur à 8. C'est parce qu'il doit être suffisamment grand pour contenir "les unités de code à huit bits de la forme de codage Unicode UTF-8".Une contrainte supplémentaire
char
est que sa taille est toujours de 1 octet, ouCHAR_BIT
bits (d'où le nom). Ceci est indiqué explicitement dans la norme.La norme C est une référence normative pour la norme C ++, donc même si elle n'énonce pas ces exigences explicitement, C ++ requiert les plages minimales requises par la norme C (page 22), qui sont les mêmes que celles des plages de types de données sur MSDN :
signed char
: -127 à 127 (notez, pas -128 à 127; ceci accepte les plates-formes de complément à 1 et signe-amplitude)unsigned char
: 0 à 255char
: même plage quesigned char
orunsigned char
, définie par l'implémentationsigned short
: -32767 à 32767unsigned short
: 0 à 65535signed int
: -32767 à 32767unsigned int
: 0 à 65535signed long
: -2147483647 à 2147483647unsigned long
: 0 à 4294967295signed long long
: -9223372036854775807 à 9223372036854775807unsigned long long
: 0 à 18446744073709551615Une implémentation C ++ (ou C) peut définir la taille d'un type en octets
sizeof(type)
à n'importe quelle valeur, tant quesizeof(type) * CHAR_BIT
évaluée à un nombre de bits suffisamment élevé pour contenir les plages requises, etsizeof(int) <= sizeof(long)
).Dans l'ensemble, nous avons la garantie que:
char
,,signed char
etunsigned char
sont au moins 8 bitssigned short
,unsigned short
,signed int
, Etunsigned int
sont au moins 16 bitssigned long
etunsigned long
sont au moins 32 bitssigned long long
etunsigned long long
sont au moins 64 bitsAucune garantie n'est faite quant à la taille
float
ou à l'double
exception quidouble
fournit au moins autant de précision quefloat
.Les plages spécifiques à l'implémentation peuvent être trouvées dans l'en-
<limits.h>
tête en C, ou<climits>
en C ++ (ou encore mieux, baséesstd::numeric_limits
sur un modèle dans l'en-<limits>
tête).Par exemple, voici comment vous trouverez la portée maximale pour
int
:C:
C ++ :
la source
char
", et non la signification habituelle.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 32 bits.Pour les systèmes 64 bits, la norme Unix principale de facto est LP64 -
long
et le pointeur est 64 bits (maisint
32 bits). La norme Windows 64 bits est LLP64 -long long
et pointeur sont 64 bits (maislong
etint
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 / IEC 9899: 1999), mais toutes y sont autorisées.
Et, par définition,
sizeof(char)
est1
, malgré 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, quisizeof(int)
était également 1, car les deuxchar
etint
étaient 32 bits.la source
[u]int32_t
ou similaire, si vous voulez une utilisation en 64 bits[u]int64_t
... si vous n'avez pas d'en-tête pour eux, téléchargez-en ou créez-en un, de préférence avec la sélection du temps de compilation de ces types ou 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 aussi grandes, alors votre conseil vaut pour les plates-formes PC / serveurs modernes et courantes.int get_char(FILE *fp, char *c)
qui renvoie EOF ou 0 et définit*c
.uint32_t x=1,y=2;
la valeur dex-y
doit être 4294967295 sur les plates-formes où "int" est de 32 bits ou moins, et -1 sur les plates-formes où "int" est de 33 bits ou plus. En outre, ilx*y
doit être évalué en utilisant l'arithmétique modulaire pour toutes les valeurs de x et y si "int" est de 32 bits ou plus petit, et l'arithmétique conventionnelle si 65 bits ou plus, mais n'impose aucune exigence sur ce qui peut arriver avec de grandes valeurs de x et y si "int" est de 33 à 64 bits.En pratique, il n'y a rien de tel. Souvent, vous pouvez vous attendre
std::size_t
à 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.En ce qui concerne tous les autres types intégrés, cela dépend vraiment du compilateur. Voici deux extraits tirés du brouillon de travail actuel de la dernière norme C ++:
Si vous le souhaitez, vous pouvez statiquement (au moment de la compilation) affirmer la taille de ces types fondamentaux. Il alertera les gens à penser à porter votre code si la taille des hypothèses change.
la source
Il y a du standard.
La norme C90 exige que
La norme C99 exige que
Voici les spécifications C99 . La page 22 détaille les tailles de différents types intégraux.
Voici les tailles de type int (bits) pour les plates-formes Windows:
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
est garanti à 8 bits, etint16_t
est garanti à 16 bits, etc.la source
sizeof(long) < sizeof(long long)
par opposition au symétriquesizeof(long) <= sizeof(long long)
?Si vous avez besoin de types de taille fixe, utilisez des types comme uint32_t (entier non signé 32 bits) défini dans stdint.h . Ils sont spécifiés en C99 .
la source
CHAR_BIT == 16
, par exemple, n'aura pasint8_t
. Toute plate - forme ne pas utiliser le complément de deux n'aura aucune d'entre eux (comme complément à deux est requis par la norme).Mise à jour: C ++ 11 a officiellement introduit les types de TR1 dans la norme:
Et les types "dimensionnés" de
<cstdint>
De plus, vous obtenez:
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é:
Ce qui signifie "rapide", s'il en est, dépend de la mise en œuvre. Il ne doit pas non plus être le plus rapide à toutes fins.
la source
La norme C ++ le dit comme ceci:
3.9.1, §2:
La conclusion: cela dépend de l'architecture sur laquelle vous travaillez. Toute autre hypothèse est fausse.
la source
Non, il n'y a pas de norme pour les tailles de caractères. La norme requiert uniquement que:
La meilleure chose que vous puissiez faire si vous voulez des variables de tailles fixes est d'utiliser des macros comme celle-ci:
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 .
la source
#include <boost/cstdint.hpp>
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:
Ainsi, lorsque nous transférons le code sur une machine différente où la taille de long int est en fait de 4, nous pouvons simplement redéfinir la seule occurrence de int.
la source
<stdint.h>
(C99 et versions ultérieures, et quel que soit le standard C ++ adopté la version C99 de la bibliothèque C).Pour les nombres à virgule flottante, il existe une norme (IEEE754) : les flottants sont 32 bits et les doubles sont 64. Il s'agit d'une norme matérielle, pas d'une norme C ++, de sorte que les compilateurs pourraient théoriquement définir flottant et doubler à une autre taille, mais en pratique, je '' Je n'ai jamais vu une architecture utilisant quelque chose de différent.
la source
double
a la même taille quefloat
(etint
la même quechar
, les deux sont 16 bits). Mais ils ont un 64 bitslong double
.Il existe une norme et elle est précisée dans les différents documents de normes (ISO, ANSI et ainsi de suite).
Wikipedia a une grande page expliquant les différents types et le maximum qu'ils peuvent stocker: Entier en informatique.
Cependant, même avec un compilateur C ++ standard, vous pouvez le découvrir relativement facilement en utilisant l'extrait de code suivant:
La documentation de std :: numeric_limits peut être trouvée 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 de tenir. Quelle que soit la plateforme sur laquelle vous vous trouvez, il existe une autre bonne page qui explique plus en détail le nombre de bits que chaque type DOIT contenir: les types int , qui sont définis dans la norme.
J'espère que ça aide!
la source
1) Tableau N1 dans l'article " Les problèmes oubliés du développement de programmes 64 bits "
2) " Modèle de données "
la source
Vous pouvez utiliser:
datatype = int
,long int
etc. Vous pourrez voir la taille du type de données que vous saisissez.la source
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 montre 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 la sortie est ordonnée en tant que telle:
"Il existe cinq types d'entiers signés standard: 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."
la source
sizeof(char)
ne doit pas être inclus.Comme mentionné, la taille doit refléter l'architecture actuelle. Vous pouvez faire un tour
limits.h
si vous voulez voir comment votre compilateur actuel gère les choses.la source
Comme d'autres l'ont répondu, les "normes" laissent toutes la plupart des détails comme "implémentation définie" et indiquent seulement que le type "char" est au moins "char_bis" large, et que "char <= short <= int <= long < = long long "(float et double sont à peu près cohérents avec les normes IEEE à virgule flottante, et long double est généralement identique à double - mais peut être plus grand sur les implémentations plus actuelles).
Une partie des raisons pour ne pas avoir de valeurs très spécifiques et exactes est que des 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 dans lesquels la taille de mot "char" peut être de 4 bits ou 7 bits, ou même une valeur autre que les ordinateurs "8/16/32/64 bits" auxquels l'utilisateur moyen d'un ordinateur domestique est exposé. (La taille des mots signifie ici combien de bits de large le système fonctionne normalement - Encore une fois, ce n'est pas toujours 8 bits comme les utilisateurs d'ordinateurs personnels peuvent s'y attendre.)
Si vous avez vraiment besoin d'un objet (dans le 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 des compilateurs fabriqués par la société ame mais pour différentes plates-formes. Certaines normes et pratiques (en particulier limits.h et similaires) sont suffisamment courantes pour que la plupart des compilateurs prennent en charge la détermination du type le mieux adapté pour une plage de valeurs spécifique, mais pas le nombre de bits utilisés. (Autrement dit, si vous savez que vous devez conserver des valeurs comprises entre 0 et 127, vous pouvez déterminer que votre compilateur prend en charge un type "int8" de 8 bits qui sera suffisamment grand pour contenir la plage complète souhaitée, mais pas quelque chose comme un type "int7" qui correspondrait exactement à 7 bits.)
Remarque: De nombreux packages source Un * x utilisaient le script "./configure" qui sonderait les capacités du compilateur / système et produirait un Makefile approprié et config.h. Vous pouvez examiner certains de ces scripts pour voir comment ils fonctionnent et comment ils sondent les capacités du comilateur / système et suivre leur exemple.
la source
Si vous êtes intéressé par une solution C ++ pure, j'ai utilisé des modèles et uniquement du code standard C ++ pour définir des types au moment de la compilation en fonction de leur taille en bits. Cela rend la solution portable sur les compilateurs.
L'idée derrière est très simple: créer une liste contenant les types char, int, short, long, long long (versions signées et non signées) et analyser la liste et en utilisant le modèle numeric_limits sélectionner le type avec la taille donnée.
En incluant cet en-tête, vous avez obtenu 8 types 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é en stdtype :: null_type également déclaré dans cet en-tête.
LE CODE CI-DESSOUS EST DONNÉ SANS GARANTIE, S'IL VOUS PLAÎT DOUBLE LE VERIFIER.
JE SUIS NOUVEAU CHEZ METAPROGRAMMING TOO, N'HÉSITEZ PAS À MODIFIER ET À CORRIGER CE CODE.
Testé avec DevC ++ (donc une version gcc autour de 3.5)
la source
où
X
est unchar
,int
,long
etc .. vous donnera la taille desX
en bits.la source
sizeof(type)*CHAR_BIT
Détient uniquementCHAR_BIT
étaient garantis à 8 bits, il<< 3
s'agit simplement d'un moyen obscur pour écrire* 8
ou* CHAR_BIT
.De Alex B La norme C ++ ne spécifie 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 de la plage requise. Vous pouvez en déduire la taille minimale en octets et la valeur de la macro CHAR_BIT qui définit le nombre de bits dans un octet (dans toutes les plates-formes sauf les plus obscures, c'est 8, et il ne peut pas être inférieur à 8).
Une contrainte supplémentaire pour char est que sa taille est toujours de 1 octet, ou CHAR_BIT bits (d'où le nom).
Les plages minimales requises par la norme (page 22) sont:
et plages de types de données sur MSDN:
caractère signé: -127 à 127 (remarque, pas -128 à 127; cela accepte les plates-formes complémentaires de 1) caractère non signé: 0 à 255 caractère "ordinaire": -127 à 127 ou 0 à 255 (dépend de la signature par défaut du caractère) signé court: -32767 à 32767 non signé court: 0 à 65535 signé int: -32767 à 32767 non signé int: 0 à 65535 signé long: -2147483647 à 2147483647 non signé long: 0 à 4294967295 signé long long: -9223372036854775807 à 9223372036854775807 non signé 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 suffisamment pour contenir les plages requises et 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 en C, ou en C ++ (ou encore mieux, les modèles std :: numeric_limits dans l'en-tête).
Par exemple, voici comment vous trouverez la plage maximale pour int:
C:
C ++:
C'est exact, cependant, vous aviez également raison de dire que: char: 1 octet court: 2 octets int: 4 octets long: 4 octets float: 4 octets double: 8 octets
Parce que les architectures 32 bits sont toujours par défaut et les plus utilisées, et elles ont conservé ces tailles standard depuis les jours pré-32 bits où la mémoire était moins disponible, et pour la compatibilité et la normalisation en amont, elle est restée la même. Même les systèmes 64 bits ont tendance à les utiliser et ont des extensions / modifications. Veuillez vous y référer pour plus d'informations:
http://en.cppreference.com/w/cpp/language/types
la source
Je remarque que toutes les autres réponses ici se sont concentrées presque exclusivement sur les types intégraux, tandis que le questionneur a également posé des questions sur les virgules flottantes.
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 binaire (ainsi que certains formats BCD, dont je n'ai jamais vu la prise en charge dans les compilateurs C ++):
Comment cette mappe sur les types C ++, alors? Généralement, il
float
utilise une seule précision; ainsisizeof(float) = 4
.double
Utilise ensuite la double précision (je crois que c'est la source du nomdouble
), etlong double
peut être double ou quadruple précision (c'est quadruple sur mon système, mais sur les systèmes 32 bits, cela peut être double). Je ne connais aucun compilateur offrant des virgules flottantes de demi-précision.En résumé, c'est l'habituel:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 ou 16la source
Comme vous l'avez mentionné - cela dépend en grande partie du compilateur et de la plate-forme. Pour cela, consultez la norme ANSI, http://home.att.net/~jackklein/c/inttypes.html
Voici celle du compilateur Microsoft: Plages de types de données .
la source
Vous pouvez utiliser des variables fournies par des bibliothèques telles que OpenGL , Qt , etc.
Par exemple, Qt fournit qint8 (garanti 8 bits sur toutes les plates-formes prises en charge par Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.
la source
Sur une machine 64 bits:
la source
int
c'est 8 octets, mais l'autre n'est pas garanti. Il n'y a rien qui dit que celachar
ne devrait être que de 8 bits. Il est autorisé à l'avoirsizeof(void*)==4
même s'il s'agit de 64 bits.Il existe quatre types d'entiers basés sur la taille:
la source
short
,int
etlong
tous les entiers 32 bits.int
, pas le mot "entier".