Conclusione finale: l'aritmetica su a void*
è illegale sia in C che in C ++.
GCC lo consente come estensione, vedi Arithmetic on void
- e Function-Pointers (nota che questa sezione fa parte del capitolo "C Extensions" del manuale). Clang e ICC probabilmente consentono l' void*
aritmetica ai fini della compatibilità con GCC. Altri compilatori (come MSVC) non consentono l'aritmetica void*
e GCC non lo consente se -pedantic-errors
viene specificato il -Werror-pointer-arith
flag o se viene specificato il flag (questo flag è utile se la propria base di codice deve essere compilata anche con MSVC).
Lo standard C parla
Le citazioni sono tratte dalla bozza n1256.
La descrizione dello standard dell'operazione di aggiunta afferma:
6.5.6-2: Inoltre, entrambi gli operandi devono avere un tipo aritmetico oppure un operando deve essere un puntatore a un tipo di oggetto e l'altro deve avere un tipo intero.
Quindi, la domanda qui è se void*
è un puntatore a un "tipo di oggetto", o equivalentemente, se void
è un "tipo di oggetto". La definizione di "tipo di oggetto" è:
6.2.5.1: I tipi sono suddivisi in tipi di oggetti (tipi che descrivono completamente gli oggetti), tipi di funzione (tipi che descrivono le funzioni) e tipi incompleti (tipi che descrivono gli oggetti ma mancano delle informazioni necessarie per determinarne le dimensioni).
E lo standard definisce void
come:
6.2.5-19: il void
tipo comprende un insieme di valori vuoto; è un tipo incompleto che non può essere completato.
Poiché void
è un tipo incompleto, non è un tipo di oggetto. Pertanto non è un operando valido per un'operazione di aggiunta.
Pertanto non è possibile eseguire l'aritmetica del puntatore su un void
puntatore.
Appunti
Inizialmente, si pensava che l' void*
aritmetica fosse consentita, a causa di queste sezioni dello standard C:
6.2.5-27: Un puntatore a vuoto deve avere gli stessi
requisiti di rappresentazione e allineamento di un puntatore a un tipo di carattere.
Però,
Gli stessi
requisiti di rappresentazione e allineamento implicano l'intercambiabilità degli argomenti alle funzioni, restituiscono valori dalle funzioni e membri dei sindacati.
Quindi questo significa che printf("%s", x)
ha lo stesso significato se x
ha tipo char*
o void*
, ma non significa che puoi fare l'aritmetica su a void*
.
Nota del redattore: questa risposta è stata modificata per riflettere la conclusione finale.