Si un type particulier (par exemple, int
, char
, float
, ..) est incrémenté, la valeur de la variable pointeur augmentée d'un nombre égal à la taille de le type de données particulier. Si un pointeur void
indique des données de x
taille pour l'opération d'incrémentation, comment va-t-il pointer sur x
taille? Comment le compilateur sait-il ajouter x
à la valeur du pointeur?
Réponses
Trop de publicités?Conclusion finale: l'arithmétique sur un void*
est illégal en C et C++.
GCC permet comme une extension, voir l'Arithmétique sur void
- et la Fonction de Pointeurs (notez que cette section est une partie de la "C" Extensions chapitre de ce manuel). Clang et de la CCI, susceptibles de permettre void*
de l'arithmétique pour les fins de compatibilité avec GCC. D'autres compilateurs (tels que MSVC) refuser l'arithmétique sur void*
, et GCC ne l'autorise pas si l' -pedantic-errors
drapeau est spécifié, ou si l' -Werror-pointer-arith
drapeau est spécifié (cette option est utile si votre base de code doit également compiler avec MSVC).
Le C Standard Parle
Les citations sont prises à partir de la n1256 projet.
Le standard de description de l'opération d'addition des états:
6.5.6-2: De plus, soit les deux les opérandes doivent avoir de l'arithmétique de type, ou l'un des opérandes est un pointeur vers un type d'objet, et l'autre est ont type entier.
Donc, la question est de savoir si l' void*
est un pointeur vers un "type d'objet", ou, de manière équivalente, si void
est un "type d'objet". La définition de "type d'objet" est:
6.2.5.1: Types sont répartis dans des types d'objets (types de décrire complètement les objets) , des types de fonction (les types qui décrivent les fonctions), et incomplète types (types de décrire des objets, mais le manque d'informations nécessaires pour déterminer leur taille).
Et la norme définit void
comme:
6.2.5-19: Le
void
type comprend un ensemble vide de valeurs; c'est un type incomplète qui ne peuvent pas être achevé.
Depuis void
est un type incomplète, il n'est pas un type d'objet. Il n'est donc pas valide opérande à une opération d'addition.
Par conséquent, vous ne pouvez pas effectuer l'arithmétique des pointeurs sur un void
pointeur.
Notes
À l'origine, on pensait que c' void*
arithmétique a été autorisée, en raison de ces sections de la norme C:
6.2.5-27: Un pointeur sur void doit avoir la même représentation et l'alignement exigences comme un pointeur vers un type de caractère.
Cependant,
La même représentation et l'alignement exigences visent à impliquer interchangeabilité comme arguments les fonctions, les valeurs de retour de fonctions, et des membres de syndicats.
Cela signifie donc qu' printf("%s", x)
a le même sens qu' x
type char*
ou void*
, mais cela ne signifie pas que vous pouvez faire de l'arithmétique sur un void*
.
Note de l'éditeur: Cette réponse a été modifié pour refléter la conclusion finale.