Para explicar por que é size_t
necessário existir e como chegamos aqui:
Em termos pragmáticos, size_t
e ptrdiff_t
são garantidos para ser 64 bits de largura em uma implementação de 64 bits, 32 bits de largura em uma implementação de 32 bits, e assim por diante. Eles não podiam forçar nenhum tipo existente a significar isso, em todos os compiladores, sem quebrar o código legado.
Um size_t
ou ptrdiff_t
não é necessariamente o mesmo que um intptr_t
ou uintptr_t
. Eles eram diferentes em algumas arquiteturas que ainda estavam em uso quando size_t
e ptrdiff_t
foram adicionados ao padrão no final dos anos 80, e tornando-se obsoleto quando C99 acrescentou muitos novos tipos, mas ainda não passaram (como Windows de 16 bits). O x86 no modo protegido de 16 bits tinha uma memória segmentada em que a maior matriz ou estrutura possível podia ter apenas 65.536 bytes de tamanho, mas um far
ponteiro precisava ter 32 bits de largura, mais largo que os registros. Nesses, intptr_t
teria 32 bits de largura, mas size_t
eptrdiff_t
pode ter 16 bits de largura e caber em um registro. E quem sabia que tipo de sistema operacional poderia ser escrito no futuro? Em teoria, a arquitetura i386 oferece um modelo de segmentação de 32 bits com ponteiros de 48 bits que nenhum sistema operacional jamais usou.
O tipo de deslocamento de memória não pode ser long
porque muito código legado supõe que long
seja exatamente 32 bits de largura. Essa suposição foi incorporada às APIs do UNIX e do Windows. Infelizmente, muitos outros códigos herdados também assumiram que a long
é grande o suficiente para conter um ponteiro, um deslocamento de arquivo, o número de segundos decorridos desde 1970 e assim por diante. O POSIX agora fornece uma maneira padronizada de forçar a última suposição a ser verdadeira, em vez da anterior, mas nenhuma é uma suposição portátil a ser feita.
Não poderia ser int
porque apenas um punhado de compiladores nos anos 90 tinham int
64 bits de largura. Então eles realmente ficaram estranhos mantendo long
32 bits de largura. A próxima revisão do Padrão declarou ilegal int
que fosse maior do que long
, mas int
ainda tem 32 bits de largura na maioria dos sistemas de 64 bits.
Não poderia ser long long int
, o que de qualquer maneira foi adicionado mais tarde, pois foi criado para ter pelo menos 64 bits de largura, mesmo em sistemas de 32 bits.
Portanto, era necessário um novo tipo. Mesmo que não fosse, todos esses outros tipos significavam algo diferente de um deslocamento dentro de uma matriz ou objeto. E se houvesse uma lição do fiasco da migração de 32 para 64 bits, seria específico sobre quais propriedades um tipo precisava ter, e não usar uma que significasse coisas diferentes em programas diferentes.
int
sesome_size
estiver assinado,size_t
se não estiver assinado.