Ist size_t
die Wortgröße der Maschine, die den Code kompiliert hat?
Parsing mit g++, meine Compiler-Ansichten size_t
als ein long unsigned int
. Wählt der Compiler intern die Größe von size_t
oder ist size_t
tatsächlich in ein Präprozessor-Makro eingegeben stddef.h
auf die Wortgröße, bevor der Compiler aufgerufen wird?
Oder bin ich ganz daneben?
Im C++-Standard [support.types] (18.2) /6: „Der Typus size_t
ist ein implementierungsdefinierter unsigned Integer-Typ, der groß genug ist, um die Größe eines beliebigen Objekts in Byte aufzunehmen.”
Dies kann mit einer “Wortgröße” identisch sein oder auch nicht, was auch immer das bedeutet.
Nein; size_t
ist nicht unbedingt das, was Sie mit “der Wortgröße” der Maschine meinen, die den Code ausführt (im Fall einer Kreuzkompilierung) oder die den Code kompiliert hat (im Normalfall, wenn der Code auf demselben Maschinentyp ausgeführt wird die den Code kompiliert haben). Es ist ein vorzeichenloser ganzzahliger Typ, der groß genug ist, um die Größe (in Byte) des größten Objekts aufzunehmen, das die Implementierung zuordnen kann.
Etwas Geschichte von sizeof
und size_t
Ich weiß nicht wann size_t
wurde genau eingeführt, aber es war zwischen 1979 und 1989. Die 1. Ausgabe von K&R Die Programmiersprache C von 1978 hat keine Erwähnung size_t
. Die 7. Ausgabe des Unix-Programmierhandbuchs erwähnt dies nicht size_t
überhaupt, und das stammt aus dem Jahr 1979. Das Buch “The UNIX Programming Environment” von Kernighan und Pike aus dem Jahr 1984 findet keine Erwähnung size_t
im Index (noch von malloc()
oder free()
, etwas zu meiner Überraschung), aber das ist nur ein Hinweis, nicht schlüssig. Der C89-Standard hat das sicherlich size_t
.
Die C99 Begründung dokumentiert einige Informationen über sizeof()
und size_t
:
6.5.3.4 Die Größe des Operators
Es ist grundlegend für die korrekte Verwendung von Funktionen wie z malloc
und fread
das
sizeof(char)
genau einer sein. In der Praxis bedeutet dies, dass ein Byte in C-Termen die kleinste Speichereinheit ist, selbst wenn diese Einheit 36 Bit breit ist; und alle Objekte bestehen aus einer ganzen Zahl dieser kleinsten Einheiten. Gilt auch, wenn der Speicher bitadressierbar ist. C89 definierte wie K&R das Ergebnis der sizeof
Der Operator muss eine Konstante vom Typ einer vorzeichenlosen Ganzzahl sein. Gängige Implementierungen und allgemeine Verwendung haben oft angenommen, dass der resultierende Typ ist int
. Alter Code, der von diesem Verhalten abhängt, war nie auf Implementierungen übertragbar, die das Ergebnis als einen anderen Typ als definieren int
. Das C89-Komitee hielt es nicht für angemessen, die Sprache zu ändern, um falschen Code zu schützen.
Die Art von sizeof
was auch immer es ist, wird veröffentlicht (in der Kopfzeile der Bibliothek <stddef.h>
) wie
size_t
, da es für den Programmierer nützlich ist, sich auf diesen Typ beziehen zu können. Diese Anforderung schränkt implizit ein size_t
ein Synonym für einen vorhandenen vorzeichenlosen ganzzahligen Typ sein. Beachten Sie auch das, obwohl size_t
ist ein vorzeichenloser Typ, sizeof
beinhaltet keine arithmetischen Operationen oder Konvertierungen, die zu einem Modulus-Verhalten führen würden, wenn die Größe zu groß ist, um als a dargestellt zu werden
size_t
wodurch jede Vorstellung zunichte gemacht wird, dass das größte deklarierbare Objekt zu groß sein könnte, um selbst mit an überspannt zu werden unsigned long
in C89 bzw uintmax_t
im C99. Dies schränkt auch die maximale Anzahl von Elementen ein, die in einem Array deklariert werden können, da für jedes Array a
von N
Elemente,
N == sizeof(a)/sizeof(a[0])
Daher size_t
ist auch ein praktischer Typ für Array-Größen und wird daher in mehreren Bibliotheksfunktionen verwendet. […]
7.17 Gemeinsame Definitionen
<stddef.h>
ist ein Header, der erfunden wurde, um Definitionen verschiedener Typen und Makros bereitzustellen, die häufig in Verbindung mit der Bibliothek verwendet werden: ptrdiff_t
, size_t
, wchar_t
und NULL
. Das Einschließen eines beliebigen Headers, der auf eines dieser Makros verweist, definiert es ebenfalls, eine Ausnahme von der üblichen Bibliotheksregel, dass jedes Makro oder jede Funktion zu genau einem Header gehört.
Beachten Sie, dass dies ausdrücklich erwähnt, dass die <stddef.h>
wurde vom C89-Komitee erfunden. Ich habe keine Worte gefunden, die das sagen size_t
wurde ebenfalls vom C89-Komitee erfunden, aber wenn nicht, war es eine Kodifizierung einer ziemlich neuen Entwicklung in C.
In einem Kommentar zu bmargulies Antwort sagt vonbrand, dass „es [size_t
] ist sicherlich ein ANSI-C-ismus’. Ich kann sehr leicht glauben, dass es eine Innovation mit dem ursprünglichen ANSI (ISO) C war, obwohl es etwas seltsam ist, dass die Begründung dies nicht besagt.
Nicht unbedingt. Die C-ISO-Spezifikation (§17.1/2) definiert size_t
wie
size_t, das ist der vorzeichenlose ganzzahlige Typ des Ergebnisses von sizeof
Operator
Mit anderen Worten, size_t
muss groß genug sein, um die Größe jedes Ausdrucks aufzunehmen, der erzeugt werden könnte sizeof
. Dies könnte die Maschinenwortgröße sein, aber sie könnte dramatisch kleiner sein (wenn der Compiler beispielsweise die maximale Größe von Arrays oder Objekten begrenzt hat) oder dramatisch größer (wenn der Compiler Sie Objekte erstellen lassen würde, die so groß sind, dass eine einzelne Maschine Word konnte die Größe dieses Objekts nicht speichern).
Hoffe das hilft!
size_t war ursprünglich nur eine Typedef in sys/types.h (traditionell unter Unix/Linux). Es wurde angenommen, dass es “groß genug” für beispielsweise die maximale Größe einer Datei oder die maximale Zuweisung mit malloc ist. Im Laufe der Zeit haben sich jedoch Standardkomitees daran gehalten, und so wurde es in viele verschiedene Header-Dateien kopiert und jedes Mal mit seinem eigenen #ifdef-Schutz vor Mehrfachdefinition geschützt. Andererseits trübte das Aufkommen von 64-Bit-Systemen mit sehr großen potenziellen Dateigrößen seine Rolle. Es ist also ein bisschen wie ein Palimpset.
Sprachstandards bezeichnen es jetzt als in stddef.h lebend. Es hat keine notwendige Beziehung zur Hardware-Wortgröße und keine Compiler-Magie. Siehe andere Antworten in Bezug darauf, was diese Standards darüber aussagen, wie groß es ist.
Solche Definitionen sind alle implementierungsdefiniert. Ich würde sizeof(char *) oder vielleicht sizeof(void *) verwenden, wenn ich eine bestmögliche Größe benötigen würde. Das Beste, was dies ergibt, ist die scheinbare Wortgröße, die die Software verwendet … was die Hardware wirklich hat, kann anders sein (z. B. kann ein 32-Bit-System 64-Bit-Integer per Software unterstützen).
Auch wenn Sie neu in den C-Sprachen sind, finden Sie in stdint.h alle möglichen Materialien zu ganzzahligen Größen.
Obwohl die Definition nicht direkt angibt, welcher Typ genau ist size_t
ist, und erfordert nicht einmal eine Mindestgröße, gibt es indirekt einige gute Hinweise. EIN size_t
muss in der Lage sein, die Größe in Bytes eines beliebigen Objekts zu enthalten, mit anderen Worten, es muss die Größe des größtmöglichen Objekts enthalten können.
Das größtmögliche Objekt ist ein Array (oder eine Struktur) mit einer Größe, die dem gesamten verfügbaren Adressraum entspricht. Ein Verweis auf a ist nicht möglich größer Objekt auf sinnvolle Weise, und abgesehen von der Verfügbarkeit von Auslagerungsspeicher gibt es keinen Grund, warum dies erforderlich sein sollte kleiner.
Daher ist nach dem Wortlaut der Definition size_t
muss mindestens 32 Bit auf einer 32-Bit-Architektur und mindestens 64 Bit auf einem 64-Bit-System sein. Es ist natürlich möglich, eine Implementierung größer zu wählen size_t
aber das ist normalerweise nicht der Fall.
Mach dir keine Sorgen. Dies ist eine berechtigte Frage.
– Scones
9. Februar 2013 um 22:02 Uhr
Was versuchst du zu machen?
– Nemo
9. Februar 2013 um 22:05 Uhr
Ich versuche nur zu verstehen, was es ist.
– Weg
9. Februar 2013 um 22:13 Uhr
Dann beantworten die Zitate aus den folgenden Normen Ihre Frage genau. Ihr Compiler kann jeden gewünschten vorzeichenlosen ganzzahligen Typ verwenden
size_t
solange es groß genug ist, um die Größe eines beliebigen Objekts darzustellen, und das ist alles, was Sie beim Schreiben von C- oder C++-Code davon ausgehen können.– Nemo
9. Februar 2013 um 22:16 Uhr
Obwohl alle diese Antworten richtig sind, habe ich niemanden gesehen, der das erwähnt hat
size_t
ist ziemlich oft die Wortgröße der Maschine. (Und mit “ziemlich oft” meine ich wörtlich: fast alle – wie in, ich habe noch nie von einer einzigen Umgebung gehört, in der dies nicht der Fall ist.)– Mystisch
9. Februar 2013 um 23:42 Uhr