Ich suche nach detaillierten Informationen bezüglich der Größe grundlegender C ++ - Typen. Ich weiß, dass es von der Architektur (16 Bit, 32 Bit, 64 Bit) und dem Compiler abhängt.
Aber gibt es Standards für C ++?
Ich verwende Visual Studio 2008 auf einer 32-Bit-Architektur. Folgendes bekomme ich:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double: 8 bytes
Ich habe versucht zu finden, ohne viel Erfolg, zuverlässige Informationen unter Angabe der Größen char
, short
, int
, long
, double
, float
(und andere Arten ich nicht gedacht) unter verschiedenen Architekturen und Compiler.
int16_t
,int32_t
undint64_t
(brauche dasiostream
Include dafür, wenn ich mich richtig erinnere). Das Schöne daran ist, dass int64_t auf einem 32-Bit-System keine Probleme haben sollte (dies wirkt sich jedoch auf die Leistung aus).<cstdint>
, nicht<iostream>
.Antworten:
Der C ++ - Standard gibt nicht die Größe von Integraltypen in Bytes an, sondern Mindestbereiche, die sie halten müssen. Sie können die Mindestgröße in Bit aus dem erforderlichen Bereich ableiten. Daraus können Sie die Mindestgröße in Bytes und den Wert des
CHAR_BIT
Makros ableiten , das die Anzahl der Bits in einem Byte definiert . Auf allen außer den dunkelsten Plattformen ist es 8, und es kann nicht weniger als 8 sein. Das liegt daran, dass es groß genug sein muss, um "die 8-Bit-Codeeinheiten der Unicode UTF-8-Codierungsform" aufzunehmen.Eine zusätzliche Einschränkung
char
besteht darin, dass seine Größe immer 1 Byte oderCHAR_BIT
Bits beträgt (daher der Name). Dies ist in der Norm ausdrücklich angegeben.Der C-Standard ist eine normative Referenz für den C ++ - Standard. Obwohl diese Anforderungen nicht explizit angegeben werden, erfordert C ++ die vom C-Standard geforderten Mindestbereiche (Seite 22), die mit denen ab Datentypbereichen identisch sind MSDN :
signed char
: -127 bis 127 (Anmerkung, nicht -128 bis 127; dies ermöglicht Plattformen mit 1er-Komplement und Vorzeichen und Größe)unsigned char
: 0 bis 255char
: gleicher Bereich wiesigned char
oderunsigned char
, implementierungsdefiniertsigned short
: -32767 bis 32767unsigned short
: 0 bis 65535signed int
: -32767 bis 32767unsigned int
: 0 bis 65535signed long
: -2147483647 bis 2147483647unsigned long
: 0 bis 4294967295signed long long
: -9223372036854775807 bis 9223372036854775807unsigned long long
: 0 bis 18446744073709551615Eine C ++ (oder C) -Implementierung kann die Größe eines Typs in Bytes
sizeof(type)
für einen beliebigen Wert definieren, solangesizeof(type) * CHAR_BIT
mit einer Anzahl von Bits ausgewertet, die hoch genug sind, um die erforderlichen Bereiche zu enthaltensizeof(int) <= sizeof(long)
. B. ).Wenn wir das alles zusammenfassen, ist uns garantiert, dass:
char
,,signed char
undunsigned char
sind mindestens 8 Bitssigned short
,unsigned short
,signed int
, Undunsigned int
sind mindestens 16 Bitssigned long
undunsigned long
sind mindestens 32 Bitsigned long long
undunsigned long long
sind mindestens 64 BitEs wird keine Garantie für die Größe von
float
oder übernommen,double
außer dass diesdouble
mindestens so viel Präzision bietet wiefloat
.Die tatsächlichen implementierungsspezifischen Bereiche finden Sie im
<limits.h>
Header in C oder<climits>
in C ++ (oder noch besserstd::numeric_limits
im<limits>
Header).So finden Sie beispielsweise die maximale Reichweite für
int
:C:
C ++ :
quelle
char
" zu bedeuten , und nicht die übliche Bedeutung.Für 32-Bit-Systeme ist der De-facto-Standard ILP32 - das heißt
int
,long
und Zeiger sind alle 32-Bit-Größen.Bei 64-Bit-Systemen ist der primäre Unix-De-facto-Standard LP64 -
long
und der Zeiger ist 64-Bit (aberint
32-Bit). Die Windows 64-Bit - Standard ist LLP64 -long long
und Zeiger sind 64-Bit (aberlong
undint
sind jeweils 32-bit).Zu einer Zeit verwendeten einige Unix-Systeme eine ILP64-Organisation.
Keine dieser De-facto-Normen ist in der C-Norm (ISO / IEC 9899: 1999) gesetzlich geregelt, aber alle sind von dieser zugelassen.
Und per Definition
sizeof(char)
ist dies1
ungeachtet des Tests im Perl-Konfigurationsskript der Fall.Beachten Sie, dass es Maschinen (Crays)
CHAR_BIT
gab, die viel größer als 8 waren. Das bedeutete, IIRC, dassizeof(int)
war auch 1, weil beidechar
undint
32-Bit waren.quelle
[u]int32_t
oder ähnliches wünschen, wenn Sie eine 64-Bit-Verwendung wünschen[u]int64_t
... wenn Sie keinen Header für sie haben, laden Sie einen herunter oder erstellen Sie einen, vorzugsweise mit einer Auswahl der Kompilierungszeit von solche Typen oder statische Zusicherungen zur Überprüfung der Größe. pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html Wenn die genauen Größen nicht so wichtig sind und Sie sich nur darum kümmern, dass sie mindestens so groß sind, gilt Ihr Rat für gängige moderne PC / Server-Plattformen.int get_char(FILE *fp, char *c)
die EOF oder 0 zurückgibt und setzt*c
.uint32_t x=1,y=2;
der Wert vonx-y
4294967295 auf Plattformen sein muss, auf denen "int" 32 Bit oder kleiner ist, und -1 auf Plattformen, auf denen "int" 33 Bit oder mehr beträgt. Ferner erfordert es, dassx*y
eine modulare Arithmetik für alle Werte von x und y ausgewertet werden muss, wenn "int" 32 Bit oder kleiner ist, und eine konventionelle Arithmetik, wenn 65 Bit oder mehr, aber keine Anforderungen an das, was mit großen Werten passieren kann von x und y, wenn "int" 33 bis 64 Bit beträgt.In der Praxis gibt es so etwas nicht. Oft können Sie erwarten
std::size_t
, dass die vorzeichenlose native Ganzzahlgröße in der aktuellen Architektur dargestellt wird. dh 16-Bit, 32-Bit oder 64-Bit, aber dies ist nicht immer der Fall, wie in den Kommentaren zu dieser Antwort ausgeführt.Was alle anderen integrierten Typen betrifft, hängt dies wirklich vom Compiler ab. Hier sind zwei Auszüge aus dem aktuellen Arbeitsentwurf des neuesten C ++ - Standards:
Wenn Sie möchten, können Sie die Größe dieser grundlegenden Typen statisch (zur Kompilierungszeit) festlegen. Es macht die Leute darauf aufmerksam, über die Portierung Ihres Codes nachzudenken, wenn sich die Größe der Annahmen ändert.
quelle
Es gibt Standard.
Der C90-Standard erfordert dies
Der C99-Standard erfordert dies
Hier sind die C99-Spezifikationen . Page 22 Detailgrößen verschiedener integraler Typen.
Hier sind die int-Typgrößen (Bits) für Windows-Plattformen:
Wenn Sie sich mit Portabilität befassen oder möchten, dass der Name des Typs die Größe widerspiegelt, können Sie sich die Kopfzeile ansehen
<inttypes.h>
, in der die folgenden Makros verfügbar sind:int8_t
ist garantiert 8 Bit undint16_t
garantiert 16 Bit usw.quelle
sizeof(long) < sizeof(long long)
im Gegensatz zum symmetrischensizeof(long) <= sizeof(long long)
?Wenn Sie Typen mit fester Größe benötigen, verwenden Sie Typen wie uint32_t (vorzeichenlose Ganzzahl 32 Bit), die in stdint.h definiert sind . Sie sind in C99 angegeben .
quelle
CHAR_BIT == 16
zum Beispiel nicht hatint8_t
. Jede Plattform, die kein Zweierkomplement verwendet, hat keine davon (da das Zweierkomplement vom Standard verlangt wird).Aktualisiert: C ++ 11 brachte die Typen von TR1 offiziell in den Standard:
Und die "Größe" Typen aus
<cstdint>
Plus bekommen Sie:
Diese Typen stellen die kleinsten Ganzzahltypen mit mindestens der angegebenen Anzahl von Bits dar. Ebenso gibt es die "schnellsten" Ganzzahltypen mit mindestens der angegebenen Anzahl von Bits:
Was "schnell" bedeutet, hängt von der Implementierung ab. Es muss auch nicht für alle Zwecke das schnellste sein.
quelle
Der C ++ Standard sagt es so:
3.9.1, §2:
Das Fazit: Es kommt darauf an, an welcher Architektur Sie arbeiten. Jede andere Annahme ist falsch.
quelle
Nein, es gibt keinen Standard für Schriftgrößen. Standard verlangt nur, dass:
Das Beste, was Sie tun können, wenn Sie Variablen fester Größe möchten, ist die Verwendung von Makros wie folgt:
Dann können Sie WORD verwenden, um Ihre Variablen zu definieren. Es ist nicht so, dass ich das mag, aber es ist der tragbarste Weg.
quelle
#include <boost/cstdint.hpp>
Wir dürfen ein Synonym für den Typ definieren, damit wir unseren eigenen "Standard" erstellen können.
Auf einer Maschine mit sizeof (int) == 4 können wir definieren:
Wenn wir also den Code auf eine andere Maschine übertragen, auf der die Größe von long int tatsächlich 4 beträgt, können wir nur das einzelne Vorkommen von int neu definieren.
quelle
<stdint.h>
(C99 und höher und je nachdem, welcher C ++ - Standard die C99-Version der C-Bibliothek übernommen hat) nicht erforderlich .Für Gleitkommazahlen gibt es einen Standard (IEEE754) : Floats sind 32 Bit und Doubles sind 64. Dies ist ein Hardwarestandard, kein C ++ - Standard, daher könnten Compiler theoretisch Float und Double auf eine andere Größe definieren, aber in der Praxis I ' Ich habe noch nie eine Architektur gesehen, die etwas anderes verwendet.
quelle
double
der die gleiche Größe wiefloat
(undint
die gleiche Größechar
, beide sind 16 Bit) hat. Aber sie haben ein 64-Bitlong double
.Es gibt eine Norm, die in den verschiedenen Normdokumenten (ISO, ANSI und so weiter) festgelegt ist.
Wikipedia hat eine großartige Seite, auf der die verschiedenen Typen und das Maximum, das sie speichern können, erklärt werden: Ganzzahl in der Informatik.
Selbst mit einem Standard-C ++ - Compiler können Sie dies mithilfe des folgenden Codeausschnitts relativ einfach herausfinden:
Die Dokumentation zu std :: numeric_limits finden Sie bei Roguewave . Es enthält eine Vielzahl weiterer Befehle, die Sie aufrufen können, um die verschiedenen Grenzwerte herauszufinden. Dies kann mit jedem beliebigen Typ verwendet werden, der Größe übermittelt, z. B. std :: Streamsize.
Johns Antwort enthält die beste Beschreibung, da diese garantiert gilt. Unabhängig davon, auf welcher Plattform Sie sich befinden, gibt es eine weitere gute Seite, auf der detaillierter beschrieben wird, wie viele Bits jeder Typ enthalten MUSS: int-Typen , die im Standard definiert sind.
Ich hoffe das hilft!
quelle
1) Tabelle N1 im Artikel " Die vergessenen Probleme bei der Entwicklung von 64-Bit-Programmen "
2) " Datenmodell "
quelle
Sie können verwenden:
datatype = int
,long int
Usw. Sie können die Größe sehen , je nachdem , welchen Datentyp angezeigt werden .quelle
Wenn es um integrierte Typen für verschiedene Architekturen und verschiedene Compiler geht, führen Sie einfach den folgenden Code auf Ihrer Architektur mit Ihrem Compiler aus, um zu sehen, was er ausgibt. Unten zeigt meine 64-Bit-Ausgabe von Ubuntu 13.04 (Raring Ringtail) g ++ 4.7.3. Bitte beachten Sie auch, was unten beantwortet wurde, weshalb die Ausgabe als solche bestellt wird:
"Es gibt fünf standardmäßige vorzeichenbehaftete Ganzzahltypen: vorzeichenbehaftetes Zeichen, kurzes int, int, langes int und langes langes int. In dieser Liste bietet jeder Typ mindestens so viel Speicherplatz wie die vorhergehenden in der Liste."
quelle
sizeof(char)
sollte nicht enthalten sein.Wie bereits erwähnt, sollte die Größe die aktuelle Architektur widerspiegeln. Sie könnten einen
limits.h
Blick darauf werfen, wenn Sie sehen möchten, wie Ihr aktueller Compiler mit Dingen umgeht.quelle
Wie andere geantwortet haben, lassen die "Standards" die meisten Details als "Implementierung definiert" und geben nur an, dass der Typ "char" mindestens "char_bis" breit ist und dass "char <= short <= int <= long < = long long "(float und double stimmen weitgehend mit den IEEE-Gleitkommastandards überein, und long double ist normalerweise dasselbe wie double - kann jedoch bei aktuelleren Implementierungen größer sein).
Ein Grund dafür, dass keine sehr spezifischen und genauen Werte vorliegen, liegt darin, dass Sprachen wie C / C ++ für eine große Anzahl von Hardwareplattformen portabel sind - einschließlich Computersystemen, bei denen die Wortgröße "char" 4 Bit betragen kann oder 7-Bit oder sogar einen anderen Wert als die "8- / 16- / 32- / 64-Bit" -Computer, denen der durchschnittliche Benutzer eines Heimcomputers ausgesetzt ist. (Die Wortgröße bedeutet hier, wie viele Bit breit das System normalerweise ist. Auch hier sind es nicht immer 8 Bit, wie es Benutzer von Heimcomputern erwarten.)
Wenn Sie wirklich ein Objekt (im Sinne einer Reihe von Bits, die einen ganzzahligen Wert darstellen) einer bestimmten Anzahl von Bits benötigen, haben die meisten Compiler eine Methode, um dies anzugeben. Aber es ist im Allgemeinen nicht portierbar, selbst zwischen Compilern der Firma ame, sondern für verschiedene Plattformen. Einige Standards und Praktiken (insbesondere limit.h und dergleichen) sind häufig genug, dass die meisten Compiler die Ermittlung des am besten geeigneten Typs für einen bestimmten Wertebereich unterstützen, jedoch nicht die Anzahl der verwendeten Bits. (Das heißt, wenn Sie wissen, dass Sie Werte zwischen 0 und 127 halten müssen, können Sie feststellen, dass Ihr Compiler einen 8-Bit-Typ vom Typ "int8" unterstützt, der groß genug ist, um den gesamten gewünschten Bereich zu halten, aber nicht so etwas wie ein Typ "int7", der für 7-Bit genau übereinstimmt.)
Hinweis: Viele Un * x-Quellpakete verwendeten das Skript "./configure", mit dem die Funktionen des Compilers / Systems überprüft und ein geeignetes Makefile und config.h ausgegeben werden. Sie können einige dieser Skripte untersuchen, um festzustellen, wie sie funktionieren und wie sie die Comiler- / Systemfunktionen prüfen, und ihren Anweisungen folgen.
quelle
Wenn Sie an einer reinen C ++ - Lösung interessiert sind, habe ich Vorlagen und nur C ++ - Standardcode verwendet, um Typen zur Kompilierungszeit basierend auf ihrer Bitgröße zu definieren. Dadurch ist die Lösung für alle Compiler portabel.
Die Idee dahinter ist sehr einfach: Erstellen Sie eine Liste mit den Typen char, int, short, long, long long (Versionen mit und ohne Vorzeichen) und scannen Sie die Liste. Wählen Sie mithilfe der Vorlage numeric_limits den Typ mit der angegebenen Größe aus.
Einschließlich dieses Headers haben Sie 8 Typ stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.
Wenn ein Typ nicht dargestellt werden kann, wird er als stdtype :: null_type ausgewertet, der ebenfalls in diesem Header deklariert ist.
DER CODE UNTEN WIRD OHNE GARANTIE GEGEBEN, BITTE DOPPELT ÜBERPRÜFEN.
Ich bin NEU BEI METAPROGRAMMIERUNG. Fühlen Sie sich frei, diesen Code zu bearbeiten und zu korrigieren.
Getestet mit DevC ++ (also eine gcc-Version um 3.5)
quelle
wo
X
ist einchar
,int
,long
etc .. wird Ihnen GrößeX
in Bits.quelle
sizeof(type)*CHAR_BIT
hältCHAR_BIT
garantiert 8 Bit wären,<< 3
ist dies nur eine verschleierte Art zu schreiben* 8
oder* CHAR_BIT
.Von Alex B Der C ++ - Standard gibt nicht die Größe von Integraltypen in Bytes an, sondern Mindestbereiche, die sie halten müssen. Sie können die Mindestgröße in Bit aus dem erforderlichen Bereich ableiten. Daraus können Sie die Mindestgröße in Bytes und den Wert des CHAR_BIT-Makros ableiten, das die Anzahl der Bits in einem Byte definiert (auf allen Plattformen außer den dunkelsten Plattformen sind es 8, und es kann nicht weniger als 8 sein).
Eine zusätzliche Einschränkung für char besteht darin, dass seine Größe immer 1 Byte oder CHAR_BIT-Bits (daher der Name) beträgt.
Die vom Standard geforderten Mindestbereiche (Seite 22) sind:
und Datentypbereiche auf MSDN:
signiertes Zeichen: -127 bis 127 (Hinweis, nicht -128 bis 127; dies bietet Platz für 1-Komplement-Plattformen) vorzeichenloses Zeichen: 0 bis 255 "einfaches" Zeichen: -127 bis 127 oder 0 bis 255 (abhängig von der Standard-Zeichen-Signatur) signiert kurz: -32767 bis 32767 unsigned short: 0 bis 65535 signiert int: -32767 bis 32767 unsigned int: 0 bis 65535 signiert long: -2147483647 bis 2147483647 unsigned long: 0 bis 4294967295 signiert long long: -9223372036854775807 bis 9223372036854775807 0 bis 18446744073709551615 Eine C ++ (oder C) -Implementierung kann die Größe eines Typs in Byte Größe von (Typ) für einen beliebigen Wert definieren, solange
Der Ausdruck sizeof (type) * CHAR_BIT ergibt die Anzahl der Bits, die ausreichen, um die erforderlichen Bereiche zu enthalten, und die Reihenfolge des Typs ist weiterhin gültig (z. B. sizeof (int) <= sizeof (long)). Die tatsächlichen implementierungsspezifischen Bereiche finden Sie im Header in C oder in C ++ (oder noch besser in std :: numeric_limits im Header).
So finden Sie beispielsweise den maximalen Bereich für int:
C:
C ++:
Dies ist richtig, aber Sie haben auch zu Recht gesagt: char: 1 Byte kurz: 2 Byte int: 4 Byte lang: 4 Byte float: 4 Byte double: 8 Byte
Da 32-Bit-Architekturen immer noch die Standardarchitektur sind und am häufigsten verwendet werden und diese Standardgrößen seit den Tagen vor 32 Bit beibehalten wurden, als weniger Speicher verfügbar war, und aus Gründen der Abwärtskompatibilität und Standardisierung gleich geblieben sind. Sogar 64-Bit-Systeme neigen dazu, diese zu verwenden und haben Erweiterungen / Modifikationen. Bitte beachten Sie dies für weitere Informationen:
http://en.cppreference.com/w/cpp/language/types
quelle
Ich stelle fest, dass sich alle anderen Antworten hier fast ausschließlich auf integrale Typen konzentriert haben, während der Fragesteller auch nach Gleitkommazahlen fragte.
Ich glaube nicht, dass der C ++ - Standard dies erfordert, aber Compiler für die gängigsten Plattformen folgen heutzutage im Allgemeinen dem IEEE754-Standard für ihre Gleitkommazahlen. Dieser Standard spezifiziert vier Arten von binären Gleitkommazahlen (sowie einige BCD-Formate, für die ich in C ++ - Compilern noch nie Unterstützung gesehen habe):
Wie ordnet sich das dann C ++ - Typen zu? Im Allgemeinen
float
verwendet die einfache Genauigkeit; also ,sizeof(float) = 4
. Danndouble
verwendet doppelte Genauigkeit (ich glaube , das ist die Quelle des Namendouble
) undlong double
kann entweder doppelte oder vierfache Präzision sein (es ist vervierfachen auf meinem System, aber auf 32-Bit - Systemen kann es doppelt so hoch sein). Ich kenne keine Compiler, die Gleitkommazahlen mit halber Genauigkeit bieten.Zusammenfassend ist dies das Übliche:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 oder 16quelle
Wie Sie bereits erwähnt haben, hängt dies weitgehend vom Compiler und der Plattform ab. Überprüfen Sie hierzu den ANSI-Standard http://home.att.net/~jackklein/c/inttypes.html
Hier ist die für den Microsoft-Compiler: Datentypbereiche .
quelle
Sie können Variablen verwenden, die von Bibliotheken wie OpenGL , Qt usw. bereitgestellt werden .
Zum Beispiel Qt bietet qint8 (garantiert 8-Bit auf allen von Qt unterstützten Plattformen sein), qint16, qint32, qint64, quint8, quint16, quint32, quint64 usw.
quelle
Auf einem 64-Bit-Computer:
quelle
int
es 8 Bytes, die andere ist jedoch nicht garantiert. Es gibt nichts, was besagt, dasschar
es nur 8 Bit sein sollte. Es darf habensizeof(void*)==4
, obwohl es 64 Bit ist.Es gibt vier Arten von Ganzzahlen, die auf der Größe basieren:
quelle
short
,int
undlong
alle 32 - Bit - Integer.int
, nicht das Wort "Ganzzahl".