size_t vs. uintptr_t

Der C-Standard garantiert diessize_t ist ein Typ, der jeden Array-Index enthalten kann. Dies bedeutet, dass logischerweisesize_t sollte in der Lage sein, jeden Zeigertyp zu halten. Ich habe auf einigen Websites gelesen, dass dies legal ist und / oder immer funktionieren sollte:

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

Also führte der Standard in C99 denintptr_t unduintptr_t Typen, die signierte und nicht signierte Typen sind, die garantiert Zeiger enthalten können:

uintptr_t p = (size_t) v;

Also, was ist der Unterschied zwischen der Verwendungsize_t unduintptr_t? Beide sind nicht signiert und sollten in der Lage sein, einen beliebigen Zeigertyp aufzunehmen, sodass sie funktional identisch zu sein scheinen. Gibt es einen wirklich zwingenden Grund für die Verwendung?uintptr_t (oder noch besser, avoid *) eher als einsize_tandere als Klarheit? Gibt es in einer undurchsichtigen Struktur, in der das Feld nur von internen Funktionen behandelt wird, einen Grund, dies nicht zu tun?

Aus dem gleichen Grunde,ptrdiff_t Es ist ein vorzeichenbehafteter Typ, der Zeigerunterschiede speichern kann und daher fast jeden Zeiger speichern kann, also wie unterscheidet er sich vonintptr_t?

Dienen nicht alle diese Typen im Grunde genommen trivial unterschiedlichen Versionen derselben Funktion? Wenn nein, warum? Was kann ich nicht mit einem machen, was ich nicht mit einem anderen machen kann? Wenn ja, warum hat C99 der Sprache zwei im Wesentlichen überflüssige Typen hinzugefügt?

Ich bin bereit, Funktionszeiger zu ignorieren, da sie nicht für das aktuelle Problem gelten, aber ich kann sie gerne erwähnen, da ich den Verdacht habe, dass sie für die "richtige" Antwort von zentraler Bedeutung sind.

Antworten auf die Frage(7)

Ihre Antwort auf die Frage