Considere el siguiente código C ++:
void* a = &a;
¿Por qué el compilador no se queja por usar un identificador no declarado?
Además, ¿qué considera el compilador que es la variable a
? ¿Es un puntero a un objeto vacío o es un puntero a un void*
puntero?
Respuestas:
El alcance de la declaración de variables en C ++ puede ser bastante sorprendente:
void* a = &a; ^~~~~~~~~~~~~~~~~ a declared as `void*` from here on
Por lo tanto,
&a
esvoid**
pero dado que cualquier tipo de puntero es implícitamente convertible avoid*
...fuente
a = &userfulObject
?void *a = a;
sería UB si se declara localmente, de lo contrario está bien en el ámbito del espacio de nombres.Es equivalente a
void* a; a = &a;
Por tanto,
a
ha sido declarado. Entoncesa
obtiene la dirección dea
escritaa
. Por tanto, es un puntero a un puntero vacío. (Aún no ha definido ningún objeto).fuente
a
en sí mismo es un objeto. (No todos los objetos tienen tipos definidos por el usuario en C ++)En
void* a
,a
se declara como un puntero no a unvoid
tipo sino a "cualquier" tipo (caso especial). Se asigna una dirección (posición en la memoria)a
, como a cualquier otra variable que se declare, por supuesto.Después de eso,
&a
se evalúa la expresión para inicializar la variable (tambiéna
, pero esto no es relevante) recién declarada. El tipo de&a
es "puntero a puntero a cualquier tipo", que es un caso especial de "puntero a cualquier tipo", totalmente compatible con el tipo dea
. Ergo, no hay mensaje del compilador.Corolario: no lo use
void*
si desea una verificación de tipo sólida. Todo se puede convertir en él. Todo lo contrario en sentido inverso, excepto porvoid*
sí mismo (sería una excepción innecesaria que un tipo fuera incompatible consigo mismo).Además, AFAIR, esto realmente proviene de C.
fuente