Considere o seguinte código C ++:
void* a = &a;
Por que o compilador não reclama por usar um identificador não declarado?
Além disso, o que o compilador considera ser a variável a
? É um ponteiro para um objeto vazio ou é um ponteiro para um void*
ponteiro?
Respostas:
O escopo da declaração de variáveis em C ++ pode ser bastante surpreendente:
Portanto,
&a
évoid**
mas, uma vez que qualquer tipo de ponteiro é implicitamente conversível emvoid*
...fonte
a = &userfulObject
?void *a = a;
seria UB se declarado localmente, caso contrário, está bem no escopo do namespace.É equivalente a
Portanto,
a
foi declarado. Portanto,a
obtém o endereço dea
escrito ema
. Portanto, é um ponteiro para um ponteiro vazio. (Você não definiu nenhum objeto ainda.)fonte
a
em si é um objeto. (Nem todos os objetos têm tipos definidos pelo usuário em C ++)Em
void* a
,a
é declarado como um ponteiro não para umvoid
tipo, mas para "qualquer" tipo (caso especial). Um endereço (posição na memória) é atribuído aa
, como a qualquer outra variável sendo declarada, é claro.Depois disso, a expressão
&a
é avaliada para inicializar a variável (tambéma
, mas isso não é relevante) recém-declarada. O tipo de&a
é "ponteiro para ponteiro para qualquer tipo", que é um caso especial de "ponteiro para qualquer tipo", totalmente compatível com o tipo dea
. Portanto, nenhuma mensagem do compilador.Corolário: não use
void*
se desejar uma verificação de tipo forte. Qualquer coisa pode ser convertida para ele. Exatamente o oposto na direção reversa, exceto paravoid*
si mesmo (seria uma exceção desnecessária que um tipo fosse incompatível com ele mesmo).Além disso, AFAIR isso realmente vem de C.
fonte