size_t vs. uintptr_t
O padrão C garante quesize_t
é um tipo que pode conter qualquer índice de matriz. Isso significa que, logicamente,size_t
deve ser capaz de manter qualquer tipo de ponteiro. Eu li em alguns sites que eu encontrei nos Googles que isso é legal e / ou deve sempre funcionar:
void *v = malloc(10);
size_t s = (size_t) v;
Então, em C99, o padrão introduziu ointptr_t
euintptr_t
tipos, que são tipos assinados e não assinados garantidos para manter ponteiros:
uintptr_t p = (size_t) v;
Então, qual é a diferença entre usarsize_t
euintptr_t
? Ambos são sem sinal, e ambos devem ser capazes de manter qualquer tipo de ponteiro, então eles parecem funcionalmente idênticos. Existe algum motivo real para usaruintptr_t
(ou melhor ainda, umvoid *
) ao invés de umsize_t
, além de clareza? Em uma estrutura opaca, onde o campo será tratado apenas por funções internas, existe alguma razão para não fazer isso?
Pela mesma razão,ptrdiff_t
tem sido um tipo assinado capaz de manter as diferenças de ponteiro, e, portanto, capaz de segurar mais qualquer ponteiro, assim como é distinto deintptr_t
?
Não são todos esses tipos basicamente servindo versões trivialmente diferentes da mesma função? Se não, por quê? O que não posso fazer com um deles que não posso fazer com o outro? Em caso afirmativo, por que C99 adicionou dois tipos essencialmente supérfluos ao idioma?
Estou disposto a desconsiderar indicadores de função, pois eles não se aplicam ao problema atual, mas sinta-se à vontade para mencioná-los, pois tenho uma suspeita de que eles estarão no centro da resposta "correta".