Eu tenho executado o seguinte código através de diferentes compiladores:
int main()
{
float **a;
void **b;
b = a;
}
Pelo que pude reunir, nãovoid **
é um ponteiro genérico, o que significa que qualquer conversão de outro ponteiro não deve compilar ou, pelo menos, emitir um aviso. No entanto, aqui estão meus resultados (todos feitos no Windows):
- gcc - lança um aviso, conforme o esperado.
- g ++ - Lança um erro, conforme o esperado (isso ocorre devido à digitação menos permissiva de C ++, certo?)
- MSVC (cl.exe) - Não envia nenhum aviso, mesmo com / Wall especificado.
Minha pergunta é: estou perdendo algo sobre a coisa toda e há algum motivo específico para o MSVC não produzir um aviso? MSVC faz produzir um aviso ao converter a partir void **
de float **
.
Outra observação: se eu substituir a = b
pela conversão explícita a = (void **)b
, nenhum dos compiladores emitirá um aviso. Eu pensei que deveria ser um elenco inválido. Por que não haveria avisos?
O motivo pelo qual estou fazendo essa pergunta é porque estava começando a aprender o CUDA e no Guia de programação oficial ( https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory ) o seguinte código pode ser encontrado:
// Allocate vectors in device memory
float* d_A;
cudaMalloc(&d_A, size);
que deve realizar uma conversão implícita para void **
para &d_A
, como o primeiro argumento de cudaMalloc
for do tipo void **
. Código semelhante pode ser encontrado em toda a documentação. Isso é apenas um trabalho malfeito no final da NVIDIA ou, novamente, estou perdendo alguma coisa? Como nvcc
usa o MSVC, o código é compilado sem avisos.
void**
não é um ponteiro genérico. Somente void*
é.
(void**)
é um elenco explícito no estilo c. Ele diz ao compilador para não olhar de perto o que você está fazendo e confiar em você. É uma substituição explícita do sistema de segurança de tipo e os compiladores são obrigados a aceitar basicamente qualquer tipo de conversão. Moldes no estilo C devem ser evitados, pois são poderosos demais. Use conversões em C ++ como as static_cast
que reclamarão se você estiver tentando fazer algo que não faz sentido.