he visto una función cuyo prototipo es:¿Es nulo ** un tipo aceptable en ANSI-C?
int myfunc(void** ppt)
Esta función se llama en un archivo de C como un = myfunc (MyStruct ** Q1);
donde mystruct es typedef para uno de la estructura que tenemos.
Esto funciona sin errores de compilación en MSVC6.0, pero cuando compilo con algún otro compilador de C, que da un error en el lugar donde esta función es llamada con el mensaje de error:
argumento de tipo MyStruct ** es incompatible con el parámetro de tipo void **
El argumento de myfunc() se mantiene como nula **, ya que parece ser una especie malloc genérica de función a ser llamada con varios tipos de variables de estructura para la memoria asignación
- ¿Hay algún tipo como vacío ** permitido en C estándar/cualquier compilador de C?
- ¿Cómo puedo solucionar esto? [He intentado colar el argumento de llamada de función para
mystruct**
, pero no funcionó]
-AD
Esto invoca un comportamiento indefinido (modificación de un objeto a través de un puntero a un tipo incorrecto). La API simplemente está rota; cualquier función de tipo asignación que asigne memoria genérica ('void *') necesita devolver el puntero en lugar de tomar un argumento de doble puntero. Afortunadamente, estas API rotas solo se pueden envolver para arreglarlas ... –
Modificarlo mediante un puntero diferente puede no estar bien definido, pero eso no se está haciendo aquí. Estoy lanzando para deshacerme del error y todos los punteros se pueden convertir hacia y desde punteros vacíos de una manera definida. Para evitar UB, tendrá que devolverlo al tipo correcto antes de intentar desreferenciarlo; esto es un hecho ya que no puede eliminar la referencia de un tipo 'void *' de todos modos: el compilador no conoce el tipo subyacente. El OP dejó en claro que el uso de un puntero de vacío era para poder enviar diferentes tipos de puntero, por lo que parece aceptable aquí y solo hay UB si no se devuelve correctamente. – paxdiablo
La función llamada luego modifica (o al menos accede) el objeto a través del tipo incorrecto. Lee o escribe como 'void *' cuando el tipo real es 'mystruct *' y estos tipos no son compatibles. 'void **' no es como 'void *'; no es un doble puntero universal. –