El estándar C garantiza que size_tes un tipo que puede contener cualquier índice de matriz. Esto significa que, lógicamente, size_tdebería poder contener cualquier tipo de puntero. Leí en algunos sitios que encontré en Google que esto es legal y / o siempre debería funcionar:
void *v = malloc(10);
size_t s = (size_t) v;
Entonces, en C99, el estándar introdujo los tipos intptr_ty uintptr_t, que son tipos con y sin signo garantizados para poder mantener punteros:
uintptr_t p = (size_t) v;
Entonces, ¿cuál es la diferencia entre usar size_ty uintptr_t? Ambos no están firmados, y ambos deberían poder contener cualquier tipo de puntero, por lo que parecen funcionalmente idénticos. ¿Existe alguna razón real convincente para usar uintptr_t(o mejor aún, a void *) en lugar de una size_t, aparte de la claridad? En una estructura opaca, donde el campo será manejado solo por funciones internas, ¿hay alguna razón para no hacerlo?
Del mismo modo, ptrdiff_tha sido un tipo con signo capaz de contener las diferencias de puntero y, por lo tanto, capaz de contener la mayoría de los punteros, entonces, ¿en qué se diferencia intptr_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 indicadores 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".
size_ty,uintptr_tpero ¿qué pasa conptrdiff_tyintptr_t, no podrían ambos almacenar el mismo rango de valores en casi cualquier plataforma? ¿Por qué tener tipos enteros de tamaño de puntero con signo y sin signo, especialmente siptrdiff_tya tiene el propósito de un tipo de entero de tamaño de puntero con signo?