Der C-Standard garantiert, dass dieser size_tTyp jeden Array-Index enthalten kann. Dies bedeutet, dass logischerweise size_tjeder Zeigertyp enthalten sein sollte. Ich habe auf einigen Websites, die ich auf den Googles gefunden habe, gelesen, dass dies legal ist und / oder immer funktionieren sollte:
void *v = malloc(10);
size_t s = (size_t) v;
In C99 führte der Standard die Typen intptr_tund uintptr_tein, die signierte und nicht signierte Typen sind, die garantiert Zeiger enthalten können:
uintptr_t p = (size_t) v;
Was ist der Unterschied zwischen size_tund uintptr_t? Beide sind nicht signiert und sollten in der Lage sein, jeden Zeigertyp zu halten, sodass sie funktional identisch zu sein scheinen. Gibt es einen wirklich zwingenden Grund, a uintptr_t(oder besser noch void *) a anstelle von a zu verwenden size_t, außer 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 Grund war ptrdiff_tes ein vorzeichenbehafteter Typ, der Zeigerunterschiede aufnehmen kann und daher fast jeden Zeiger aufnehmen kann. Wie unterscheidet er sich also von intptr_t?
Sind nicht alle diese Typen grundsätzlich trivial unterschiedliche Versionen derselben Funktion? Wenn nicht, warum? Was kann ich mit einem von ihnen nicht machen, was ich mit einem anderen nicht 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.
size_tund,uintptr_taber was ist mitptrdiff_tundintptr_t- könnten nicht beide den gleichen Wertebereich auf fast jeder Plattform speichern? Warum haben sowohl vorzeichenbehaftete als auch vorzeichenlose Ganzzahltypen in Zeigergröße, insbesondere wenn sieptrdiff_tbereits den Zweck eines Ganzzahlentyps in Vorzeichengröße mit Vorzeichen erfüllen?