Seite 1 von 1

size_t unter gcc und clang

Verfasst: 22.07.2026, 15:54
von starcow
Tach meine lieben ZFX'ler :)

Ich habe hier eine etwas seltsame Situation, die ich mir nur halbwegs erklären kann:

(Es wird an keiner Stelle irgendwas includiert)

Code: Alles auswählen

typedef unsigned int size_t;

int main(void)
{
	return _Generic(sizeof(0), size_t: 2, unsigned long long: 1, default: 0);
}
gcc gibt mir 1 zurück - und nicht 2.
Das lässt für mich eigentlich nur den Schluss zu: gcc hat den Typen size_t intern fest als unsigned long long "verdrahtet", resp. arbeitet womöglich erst gar nicht damit.
clang beschwert sich über eine abweichende redefinition, obwohl size_t niergends zuvor im Code als alias resp. typedef definiert wurde.
Interessant ist auch, dass ich size_t unter clang verwenden kann, ohne irgendwo ein typedef von size_t stehen zu haben.

Mein Problem mit size_t:
Es reicht nicht, irgendeinen Typen wie unsigned long long hinter der size_t "Abstraktion" zu verstecken.
Denn sobald eine Variable vom Typen size_t in einem arithmetischen Ausdruck auftaucht, ist es wichtig zu wissen, welche conversations vorgenommen werden und wohin der typ womöglich promoted wird. Denn der standard definiert für size_t eben gerade keine neuen type conversation rules, sondern es gelten nur die usual arithmetic conversions - und die beziehen sich auf die basic types.
Also reicht es leider nicht dieses "Abstraktions-Spiel" von size_t einfach blind mitzuspielen und sich zu sagen "Was auch immer size_t ist, ist Wurst - das macht der Compiler".

Klar, in der Praxis ist das heute sowieso einfach ein unsigned long long. Aber wenn ich mich in meinem Code 100% darauf verlassen muss, kann ich auch gleich direkt jeweils u64 anstelle von size_t verwenden. Dann ist es wenigstens transparent.
Es scheint mir zudem irgendwie auch ein historischer Fehler gewesen zu sein, size_t als unsigned zu definieren. Das zieht jeden arithmetischen Ausdruck in einen Restklassenring rein - und das ist eigentlich fast nie das, was man will.
Ein cast zu i64 ist zudem potentiell ungünstig, da bei einem Wert, der nicht mehr als signed dargestellt werden kann, das Verhalten IB ist.

Oder was denkt ihr dazu?

Re: size_t unter gcc und clang

Verfasst: 22.07.2026, 20:08
von xq
size_t ist ja definiert als "der Typ, welcher die maximale Objektgröße darstellen kann". Im Kontrast dazu gibt es uintptr_t (der Typ, welcher garantiert einen Pointer als Integer aufnehmen kann). Für manche Plattformen gilt, dass sizeof(size_t) != sizeof(uintptr_t) (hallo 8086 mit Segmentierung, hallo AVR mit 24-bit Code Pointer, aber 16-bit size_t).

size_t muss unsigned sein, weil du sonst nur 50% des potentiell verfügbaren Speichers als maximale Objekt-Größe hast. Sprich, eine Struktur oder ein Array können nur 32k statt 64k auf einem 16-bit System groß sein. Unpraktisch, wenn man einen 48k-Speicherblock haben möchte.

Grundlegend halte ich size_t für einen der wichtigsten Typen, und ich rate stark davon ab, irgendwelche "basic types" (int, unsigned long long, ...), weil diese eben keine definierten Größen haben und die Software damit nicht portabel ist (Auf AVR kann int auch nur 8 statt 16 Bit groß sein, je nach Compilerflags/ABI).

Ich seh da ehrlich gesagt wenig Spielraum, das ganze Thema anders zu lösen, und auch moderne Sprachen wie Rust oder Zig haben einen usize-Typ, welcher genau diese Eigenschaften abbilden kann.