Per size_t
capire perché doveva esistere e come siamo arrivati qui:
In termini pragmatici, size_t
e ptrdiff_t
sono garantiti avere 64 bit di larghezza su un'implementazione a 64 bit, 32 bit di larghezza su un'implementazione a 32 bit e così via. Non potevano forzare alcun tipo esistente a significare che, su ogni compilatore, senza rompere il codice legacy.
Un size_t
o ptrdiff_t
non è necessariamente uguale a un intptr_t
o uintptr_t
. Erano diversi su alcune architetture che erano ancora in uso quando size_t
e ptrdiff_t
furono aggiunte allo Standard alla fine degli anni '80, e divennero obsolete quando C99 aggiunse molti nuovi tipi ma non se ne andarono ancora (come Windows a 16 bit). L'x86 in modalità protetta a 16 bit aveva una memoria segmentata in cui l'array o la struttura più grande possibile poteva avere solo 65.536 byte di dimensione, ma un far
puntatore doveva essere largo 32 bit, più largo dei registri. Su quelli, intptr_t
sarebbe stato largo 32 bit ma size_t
eptrdiff_t
potrebbe essere largo 16 bit e inserito in un registro. E chi sapeva che tipo di sistema operativo potrebbe essere scritto in futuro? In teoria, l'architettura i386 offre un modello di segmentazione a 32 bit con puntatori a 48 bit che nessun sistema operativo ha mai effettivamente utilizzato.
Il tipo di offset della memoria non potrebbe essere long
dovuto al fatto che troppi codici legacy presuppongono una long
larghezza esattamente di 32 bit. Questo presupposto è stato persino integrato nelle API UNIX e Windows. Sfortunatamente, molti altri codici legacy presumevano anche che a long
fosse abbastanza largo da contenere un puntatore, un offset di file, il numero di secondi trascorsi dal 1970 e così via. POSIX ora fornisce un modo standardizzato per forzare la seconda ipotesi a essere vera invece della prima, ma nessuna delle due è una ipotesi portatile da fare.
Non potrebbe essere int
perché solo una manciata di compilatori negli anni '90 ha reso int
larga 64 bit. Quindi sono diventati davvero strani mantenendo long
32 bit di larghezza. La prossima revisione dello standard ha dichiarato illegale int
essere più ampia di long
, ma int
è ancora larga 32 bit sulla maggior parte dei sistemi a 64 bit.
Non potrebbe essere long long int
, che comunque è stato aggiunto in seguito, poiché è stato creato per essere largo almeno 64 bit anche su sistemi a 32 bit.
Quindi, era necessario un nuovo tipo. Anche se non lo fosse, tutti quegli altri tipi significavano qualcosa di diverso da un offset all'interno di un array o di un oggetto. E se c'era una lezione dal fiasco della migrazione da 32 a 64 bit, doveva essere specifica su quali proprietà un tipo avesse bisogno e non usarne una che significasse cose diverse in programmi diversi.
int
ifsome_size
è firmata,size_t
se non è firmata.