Considérez le code C ++ suivant:
void* a = &a;
Pourquoi le compilateur ne se plaint-il pas d'avoir utilisé un identifiant non déclaré?
De plus, que considère le compilateur comme étant la variable a
? Est-ce un pointeur vers un objet vide ou est-ce un pointeur vers un void*
pointeur?
Réponses:
La portée de la déclaration des variables en C ++ peut être assez surprenante:
Par conséquent,
&a
estvoid**
mais puisque tout type de pointeur est implicitement convertible envoid*
...la source
a = &userfulObject
?void *a = a;
serait UB s'il était déclaré localement, sinon cela convient à la portée de l'espace de noms.C'est équivalent à
Par conséquent,
a
a été déclaré. Obtient donca
l'adresse dea
écritea
. C'est donc un pointeur vers un pointeur vide. (Vous n'avez encore défini aucun objet.)la source
a
lui-même est un objet. (Tous les objets n'ont pas de types définis par l'utilisateur en C ++)In
void* a
,a
est déclaré comme un pointeur non pas vers unvoid
type mais vers "tout" type (cas particulier). Une adresse (position en mémoire) est affectée àa
, comme à toute autre variable déclarée, bien sûr.Après cela, l'expression
&a
est évaluée pour initialiser la variable (égalementa
, mais ce n'est pas pertinent) qui vient d'être déclarée. Le type de&a
est "pointeur vers un pointeur vers n'importe quel type", ce qui est un cas particulier de "pointeur vers n'importe quel type", entièrement compatible avec le type dea
. Ergo, pas de message du compilateur.Corollaire: ne pas utiliser
void*
si vous souhaitez une vérification de type forte. Tout peut y être converti. Juste le contraire dans le sens inverse, sauf pourvoid*
lui-même (ce serait une exception inutile qu'un type soit incompatible avec lui-même).Aussi, AFAIR cela vient vraiment de C.
la source