Ho eseguito il seguente codice attraverso diversi compilatori:
int main()
{
float **a;
void **b;
b = a;
}
Da quello che sono stato in grado di raccogliere, nonvoid **
è un puntatore generico, il che significa che qualsiasi conversione da un altro puntatore non dovrebbe compilare o almeno lanciare un avviso. Tuttavia, ecco i miei risultati (tutto fatto su Windows):
- gcc - Genera un avviso, come previsto.
- g ++ : genera un errore, come previsto (ciò è dovuto alla tipizzazione meno permissiva di C ++, giusto?)
- MSVC (cl.exe) - Non genera alcun avviso, anche con / Wall specificato.
La mia domanda è: mi sto perdendo qualcosa sull'intera faccenda e c'è qualche motivo specifico per cui MSVC non produce un avviso? MSVC fa produrre un avviso durante la conversione da void **
a float **
.
Un'altra cosa da notare: se sostituisco a = b
con la conversione esplicita a = (void **)b
, nessuno dei compilatori lancia un avvertimento. Ho pensato che questo dovesse essere un cast non valido, quindi perché non ci dovrebbero essere avvisi?
Il motivo per cui sto ponendo questa domanda è perché stavo iniziando a studiare CUDA e nella Guida di programmazione ufficiale ( https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory ) è possibile trovare il seguente codice:
// Allocate vectors in device memory
float* d_A;
cudaMalloc(&d_A, size);
che dovrebbe eseguire una conversione implicita in void **
per &d_A
, poiché il primo argomento di cudaMalloc
è di tipo void **
. Codice simile può essere trovato in tutta la documentazione. Questo è solo un lavoro sciatto da parte di NVIDIA o, di nuovo, mi manca qualcosa? Poiché nvcc
utilizza MSVC, il codice viene compilato senza avvisi.
void**
non è un puntatore generico. Lo void*
è solo .
(void**)
è un cast esplicito in stile c. Dice al compilatore di non guardare da vicino ciò che stai facendo e di fidarti di te. È una sostituzione esplicita del sistema di sicurezza dei tipi e i compilatori sono tenuti ad accettare praticamente qualsiasi tipo di conversione. I cast in stile C dovrebbero essere evitati, sono troppo potenti. Usa cast di C ++ come i static_cast
quali ti lamenterai se stai cercando di fare qualcosa che non ha senso.