Der C-Standard garantiert, dass dieser size_t
Typ jeden Array-Index enthalten kann. Dies bedeutet, dass logischerweise size_t
jeder 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_t
und uintptr_t
ein, 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_t
und 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_t
es 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_t
und,uintptr_t
aber was ist mitptrdiff_t
undintptr_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_t
bereits den Zweck eines Ganzzahlentyps in Vorzeichengröße mit Vorzeichen erfüllen?