203 votes

Arithmétique de pointeur pour pointeur vide en C

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?

325voto

ccSadegh Points 2885

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.

66voto

Job Points 8339

L'arithmétique de pointeur n'est pas autorisée sur les pointeurs void* .

27voto

Transformez-le en pointeur de caractère et incrémentez votre pointeur d'avance x octets.

14voto

Oli Charlesworth Points 148744

Vous ne pouvez pas faire d'arithmétique de pointeur sur les types void * , exactement pour cette raison!

8voto

Jakob Points 11155

Vous devez le transtyper vers un autre type de pointeur avant de faire de l'arithmétique de pointeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X