Pour expliquer pourquoi il size_t
fallait exister et comment nous en sommes arrivés là:
En termes pragmatiques, size_t
et ptrdiff_t
sont garantis à 64 bits de large sur une implémentation 64 bits, 32 bits de large sur une implémentation 32 bits, et ainsi de suite. Ils ne pouvaient forcer aucun type existant à signifier cela, sur chaque compilateur, sans casser le code hérité.
Un size_t
ou ptrdiff_t
n'est pas nécessairement le même qu'un intptr_t
ou uintptr_t
. Ils étaient différents sur certaines architectures qui étaient encore en usage quand size_t
et ptrdiff_t
ont été ajoutés à la norme à la fin des années 80, et devenant obsolètes lorsque C99 a ajouté de nombreux nouveaux types mais pas encore disparus (tels que Windows 16 bits). Le x86 en mode protégé 16 bits avait une mémoire segmentée où la plus grande matrice ou structure possible ne pouvait avoir qu'une taille de 65 536 octets, mais un far
pointeur devait avoir une largeur de 32 bits, plus large que les registres. Sur ceux-ci, intptr_t
aurait été de 32 bits de large mais size_t
etptrdiff_t
pourrait avoir une largeur de 16 bits et rentrer dans un registre. Et qui savait quel type de système d'exploitation pourrait être écrit à l'avenir? En théorie, l'architecture i386 propose un modèle de segmentation 32 bits avec des pointeurs 48 bits qu'aucun système d'exploitation n'a jamais réellement utilisé.
Le type d'un décalage de mémoire ne peut pas être long
dû au fait que trop de code hérité suppose une long
largeur exacte de 32 bits. Cette hypothèse a même été intégrée aux API UNIX et Windows. Malheureusement, beaucoup d'autres codes hérités supposaient également que a long
est suffisamment large pour contenir un pointeur, un décalage de fichier, le nombre de secondes qui se sont écoulées depuis 1970, etc. POSIX fournit désormais un moyen normalisé de forcer la dernière hypothèse à être vraie au lieu de la première, mais aucune hypothèse portable n'est à faire.
Cela ne pouvait pas être int
parce que seule une petite poignée de compilateurs dans les années 90 faisaient int
64 bits de large. Ensuite, ils sont vraiment devenus étranges en gardant une long
largeur de 32 bits. La prochaine révision de la norme l'a déclarée illégale pour int
être plus large que long
, mais elle int
est toujours de 32 bits sur la plupart des systèmes 64 bits.
Il ne pouvait pas l'être long long int
, ce qui a été ajouté de toute façon plus tard, car il a été créé pour être d'au moins 64 bits, même sur les systèmes 32 bits.
Donc, un nouveau type était nécessaire. Même si ce n'était pas le cas, tous ces autres types signifiaient autre chose qu'un décalage dans un tableau ou un objet. Et s'il y avait une leçon à tirer du fiasco de la migration de 32 à 64 bits, c'était de préciser les propriétés qu'un type devait avoir et de ne pas en utiliser une qui signifiait différentes choses dans différents programmes.
int
sisome_size
est signé,size_t
s'il n'est pas signé.