Endgültige Schlussfolgerung: Arithmetik auf a void*
ist sowohl in C als auch in C ++ illegal .
GCC erlaubt es als Erweiterung, siehe Arithmetik ein void
- und Funktionszeiger (beachten Sie, dass dieser Abschnitt Teil des Kapitels "C-Erweiterungen" des Handbuchs ist). Clang und ICC erlauben wahrscheinlich void*
Arithmetik zum Zwecke der Kompatibilität mit GCC. Andere Compiler (z. B. MSVC) lassen das Rechnen nicht zu void*
, und GCC verbietet es, wenn das -pedantic-errors
Flag angegeben ist oder wenn das -Werror-pointer-arith
Flag angegeben ist (dieses Flag ist nützlich, wenn Ihre Codebasis auch mit MSVC kompilieren muss).
Der C-Standard spricht
Zitate stammen aus dem Entwurf n1256.
In der Standardbeschreibung der Additionsoperation heißt es:
6.5.6-2: Zusätzlich müssen entweder beide Operanden einen arithmetischen Typ haben oder ein Operand muss ein Zeiger auf einen Objekttyp sein und der andere muss einen ganzzahligen Typ haben.
Die Frage hier ist also, ob void*
es sich um einen Zeiger auf einen "Objekttyp" handelt oder ob void
es sich um einen "Objekttyp" handelt. Die Definition für "Objekttyp" lautet:
6.2.5.1: Typen werden in Objekttypen (Typen, die Objekte vollständig beschreiben), Funktionstypen (Typen, die Funktionen beschreiben) und unvollständige Typen (Typen, die Objekte beschreiben, denen jedoch Informationen fehlen, die zur Bestimmung ihrer Größe erforderlich sind) unterteilt.
Und der Standard definiert void
als:
6.2.5-19: Der void
Typ umfasst einen leeren Wertesatz ; Es ist ein unvollständiger Typ, der nicht abgeschlossen werden kann.
Da void
es sich um einen unvollständigen Typ handelt, handelt es sich nicht um einen Objekttyp. Daher ist es kein gültiger Operand für eine Additionsoperation.
Daher können Sie keine Zeigerarithmetik für einen void
Zeiger ausführen .
Anmerkungen
Ursprünglich wurde angenommen, dass void*
aufgrund dieser Abschnitte des C-Standards Arithmetik zulässig ist:
6.2.5-27: Ein Zeiger auf void muss dieselben Darstellungs- und Ausrichtungsanforderungen
haben wie ein Zeiger auf einen Zeichentyp.
Jedoch,
Dieselben Darstellungs- und Ausrichtungsanforderungen
sollen Austauschbarkeit als Argumente für Funktionen, Rückgabewerte von Funktionen und Gewerkschaftsmitglieder implizieren.
Das bedeutet also, dass printf("%s", x)
es die gleiche Bedeutung hat, ob es x
einen Typ char*
oder hat void*
, aber es bedeutet nicht, dass Sie mit a rechnen können void*
.
Anmerkung des Herausgebers: Diese Antwort wurde bearbeitet, um die endgültige Schlussfolgerung widerzuspiegeln.