size_t vs. uintptr_t

El estándar C garantiza quesize_t Es un tipo que puede contener cualquier índice de matriz. Esto significa que, lógicamente,size_t Debe ser capaz de mantener cualquier tipo de puntero. He leído en algunos sitios que encontré en Google que esto es legal y / o debería funcionar siempre:

void *v = malloc(10);
size_t s = (size_t) v;

Entonces, en C99, el estándar introdujo elintptr_t yuintptr_t tipos, que son tipos firmados y sin firmar, garantizados para poder contener punteros:

uintptr_t p = (size_t) v;

Entonces, ¿cuál es la diferencia entre usarsize_t yuintptr_t? Ambos están sin firmar, y ambos deberían poder contener cualquier tipo de puntero, por lo que parecen funcionalmente idénticos. ¿Hay alguna razón convincente para usaruintptr_t (o mejor aún, unvoid *) preferible asize_t, aparte de la claridad? En una estructura opaca, donde el campo será manejado solo por funciones internas, ¿hay alguna razón para no hacer esto?

De la misma manera,ptrdiff_t ha sido un tipo con signo capaz de mantener las diferencias de puntero y, por lo tanto, capaz de contener la mayoría de los punteros, entonces, ¿cómo se distingueintptr_t?

¿No están todos estos tipos básicamente sirviendo versiones trivialmente diferentes de la misma función? Si no, ¿por qué? ¿Qué no puedo hacer con uno de ellos que no puedo hacer con otro? Si es así, ¿por qué C99 agregó dos tipos esencialmente superfluos al lenguaje?

Estoy dispuesto a ignorar los punteros de función, ya que no se aplican al problema actual, pero siéntase libre de mencionarlos, ya que tengo la sospecha de que serán fundamentales para la respuesta "correcta".

Respuestas a la pregunta(7)

Su respuesta a la pregunta