He estado ejecutando el siguiente código a través de diferentes compiladores:
int main()
{
float **a;
void **b;
b = a;
}
Por lo que he podido reunir, novoid **
es un puntero genérico, lo que significa que cualquier conversión desde otro puntero no debe compilarse o al menos lanzar una advertencia. Sin embargo, aquí están mis resultados (todo hecho en Windows):
- gcc : lanza una advertencia, como se esperaba.
- g ++ : arroja un error, como se esperaba (esto se debe a la tipificación menos permisiva de C ++, ¿verdad?)
- MSVC (cl.exe) : no genera ninguna advertencia, incluso con / Wall especificado.
Mi pregunta es: ¿Me estoy perdiendo algo acerca de todo esto y hay alguna razón específica por la cual MSVC no produce una advertencia? MSVC hace producir una advertencia al convertir de void **
a float **
.
Otra cosa a tener en cuenta: si lo reemplazo a = b
con la conversión explícita a = (void **)b
, ninguno de los compiladores arroja una advertencia. Pensé que esto debería ser un reparto no válido, entonces, ¿por qué no habría advertencias?
La razón por la que hago esta pregunta es porque estaba empezando a aprender CUDA y en la Guía de programación oficial ( https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory ) se puede encontrar el siguiente código:
// Allocate vectors in device memory
float* d_A;
cudaMalloc(&d_A, size);
que debe realizar una conversión implícita a void **
for &d_A
, ya que el primer argumento de cudaMalloc
es de tipo void **
. Se puede encontrar un código similar en toda la documentación. ¿Es solo un trabajo descuidado al final de NVIDIA o, de nuevo, me falta algo? Como nvcc
usa MSVC, el código se compila sin advertencias.
void**
no es un puntero genérico. Solo void*
es
(void**)
es un elenco explícito de estilo C. Le dice al compilador que no mire de cerca lo que está haciendo y que confíe en usted. Es una anulación explícita del tipo de sistema de seguridad y se requiere que los compiladores acepten básicamente cualquier tipo de conversión. Se deben evitar los moldes de estilo C, son demasiado poderosos. Use modelos de C ++ como los static_cast
que se quejarán si está tratando de hacer algo que no tiene sentido.