Um zu erklären, warum size_t
es existieren musste und wie wir hierher kamen:
In pragmatischen Begriffen size_t
und ptrdiff_t
bei einer 64-Bit-Implementierung mit einer Breite von 64 Bit, bei einer 32-Bit-Implementierung mit einer Breite von 32 Bit usw. garantiert. Sie konnten keinen vorhandenen Typ dazu zwingen, dies auf jedem Compiler zu bedeuten, ohne den alten Code zu beschädigen.
Ein size_t
oder ptrdiff_t
ist nicht unbedingt dasselbe wie ein intptr_t
oder uintptr_t
. Sie waren anders auf bestimmte Architekturen , die noch in Gebrauch waren , als size_t
und ptrdiff_t
wurden dem Standard - in den späten 80er Jahren hinzugefügt und veralten , wenn C99 viele neue Arten hinzugefügt , aber noch nicht gegangen (wie 16-Bit - Windows). Das x86 im 16-Bit-geschützten Modus hatte einen segmentierten Speicher, in dem das größtmögliche Array oder die größtmögliche Struktur nur 65.536 Byte groß sein konnte, ein far
Zeiger jedoch 32 Bit breit und breiter als die Register sein musste. Auf denen intptr_t
wäre aber 32 Bit breit gewesen size_t
undptrdiff_t
könnte 16 Bit breit sein und in ein Register passen. Und wer wusste, welche Art von Betriebssystem in Zukunft geschrieben werden könnte? Theoretisch bietet die i386-Architektur ein 32-Bit-Segmentierungsmodell mit 48-Bit-Zeigern, das noch kein Betriebssystem verwendet hat.
Der Typ eines Speicherversatzes könnte nicht sein, long
weil viel zu viel Legacy-Code davon ausgeht, dass er long
genau 32 Bit breit ist. Diese Annahme wurde sogar in die UNIX- und Windows-APIs integriert. Leider gingen viele andere Legacy-Codes auch davon aus, dass a long
breit genug ist, um einen Zeiger, einen Datei-Offset, die Anzahl der Sekunden, die seit 1970 vergangen sind, usw. aufzunehmen. POSIX bietet jetzt eine standardisierte Möglichkeit, die letztgenannte Annahme anstelle der ersteren als wahr zu erzwingen, aber es ist auch keine tragbare Annahme zu treffen.
Es konnte nicht sein, int
dass nur eine winzige Handvoll Compiler in den 90er Jahren int
64 Bit breit waren. Dann wurden sie wirklich komisch, indem sie long
32 Bit breit hielten . Die nächste Überarbeitung des Standards erklärte es für illegal int
, breiter als zu sein long
, ist aber int
auf den meisten 64-Bit-Systemen immer noch 32 Bit breit.
Es konnte nicht sein long long int
, was ohnehin später hinzugefügt wurde, da dieses selbst auf 32-Bit-Systemen mindestens 64 Bit breit war.
Es wurde also ein neuer Typ benötigt. Selbst wenn dies nicht der Fall wäre, bedeuteten all diese anderen Typen etwas anderes als einen Versatz innerhalb eines Arrays oder Objekts. Und wenn es eine Lehre aus dem Fiasko der 32-zu-64-Bit-Migration gab, sollte genau angegeben werden, welche Eigenschaften ein Typ haben muss, und nicht eine, die in verschiedenen Programmen unterschiedliche Bedeutungen hat.
int
ifsome_size
ist signiert,size_t
wenn es nicht signiert ist.