Para entrar en por qué size_t
necesitaba existir y cómo llegamos aquí:
En términos pragmáticos, size_t
y ptrdiff_t
se garantiza que tienen 64 bits de ancho en una implementación de 64 bits, 32 bits de ancho en una implementación de 32 bits, y así sucesivamente. No podían obligar a ningún tipo existente a querer decir eso, en cada compilador, sin romper el código heredado.
A size_t
o ptrdiff_t
no es necesariamente lo mismo que un intptr_t
o uintptr_t
. Eran diferentes en ciertas arquitecturas que todavía estaban en uso cuando size_t
y ptrdiff_t
se agregaron a la norma en los últimos años 80, y se conviertan en obsoletos cuando C99 añadió muchos nuevos tipos pero no han ido todavía (como Windows de 16 bits). El x86 en modo protegido de 16 bits tenía una memoria segmentada donde la matriz o estructura más grande posible podía tener solo 65.536 bytes de tamaño, pero un far
puntero debía tener 32 bits de ancho, más ancho que los registros. En esos, intptr_t
habría sido de 32 bits de ancho pero size_t
yptrdiff_t
podría tener 16 bits de ancho y caber en un registro. ¿Y quién sabía qué tipo de sistema operativo podría escribirse en el futuro? En teoría, la arquitectura i386 ofrece un modelo de segmentación de 32 bits con punteros de 48 bits que ningún sistema operativo ha utilizado realmente.
El tipo de compensación de memoria no podría deberse a long
que demasiado código heredado supone que long
tiene exactamente 32 bits de ancho. Esta suposición incluso se incorporó a las API de UNIX y Windows. Desafortunadamente, muchos otros códigos heredados también asumieron que a long
es lo suficientemente ancho como para contener un puntero, un desplazamiento de archivo, la cantidad de segundos que han transcurrido desde 1970, y así sucesivamente. POSIX ahora proporciona una forma estandarizada de forzar que la última suposición sea verdadera en lugar de la primera, pero tampoco es una suposición portátil.
No podría ser int
porque solo un pequeño puñado de compiladores en los años 90 tenía int
64 bits de ancho. Luego se volvieron realmente raros al mantener long
32 bits de ancho. La próxima revisión del Estándar declaró ilegal int
que sea más ancho long
, pero int
aún tiene 32 bits de ancho en la mayoría de los sistemas de 64 bits.
No podría ser long long int
, lo que de todos modos se agregó más tarde, ya que se creó para tener al menos 64 bits de ancho incluso en sistemas de 32 bits.
Entonces, se necesitaba un nuevo tipo. Incluso si no fuera así, todos esos otros tipos significaban algo más que un desplazamiento dentro de una matriz u objeto. Y si hubo una lección del fiasco de la migración de 32 a 64 bits, fue ser específico acerca de qué propiedades debía tener un tipo, y no usar uno que significara cosas diferentes en diferentes programas.
int
ifsome_size
está firmado,size_t
si no está firmado.