La norme C garantit qu'il size_ts'agit d'un type pouvant contenir n'importe quel index de tableau. Cela signifie que, logiquement, size_tdevrait pouvoir contenir n'importe quel type de pointeur. J'ai lu sur certains sites que j'ai trouvés sur Google que cela est légal et / ou devrait toujours fonctionner:
void *v = malloc(10);
size_t s = (size_t) v;
Ainsi, en C99, la norme a introduit les types intptr_tet uintptr_t, qui sont des types signés et non signés garantis pour pouvoir contenir des pointeurs:
uintptr_t p = (size_t) v;
Alors, quelle est la différence entre utiliser size_tet uintptr_t? Les deux ne sont pas signés, et les deux devraient pouvoir contenir n'importe quel type de pointeur, de sorte qu'ils semblent fonctionnellement identiques. Y a-t-il une vraie raison impérieuse d'utiliser uintptr_t(ou mieux encore, a void *) plutôt que a size_t, autre que la clarté? Dans une structure opaque, où le champ ne sera géré que par des fonctions internes, y a-t-il une raison de ne pas le faire?
De même, ptrdiff_ta-t-il été un type signé capable de contenir des différences de pointeurs, et donc capable de contenir la plupart des pointeurs, alors en quoi est-il distinct intptr_t?
Tous ces types ne servent-ils pas fondamentalement des versions trivialement différentes de la même fonction? Sinon, pourquoi? Qu'est-ce que je ne peux pas faire avec l'un d'eux que je ne peux pas faire avec un autre? Si oui, pourquoi C99 a-t-il ajouté deux types essentiellement superflus au langage?
Je suis prêt à ignorer les pointeurs de fonction, car ils ne s'appliquent pas au problème actuel, mais n'hésitez pas à les mentionner, car j'ai une suspicion sournoise, ils seront au cœur de la "bonne" réponse.
size_tetuintptr_tmais qu'en est-ilptrdiff_tetintptr_t- les deux ne pourraient-ils pas stocker la même plage de valeurs sur presque n'importe quelle plate-forme? Pourquoi avoir des types entiers de taille de pointeur signés et non signés, en particulier si celaptrdiff_tsert déjà l'objectif d'un type entier de taille de pointeur signé.