Advertencia cuando el tipo de fundición a presión entre el puntero y el puntero a la función

StackOverflow https://stackoverflow.com/questions/1556651

  •  21-09-2019
  •  | 
  •  

Pregunta

Estoy portar algo de código C a un entorno de chips DSP TI. Estoy luchando con el compilador C.

Tengo una estructura de datos que incluye un puntero a una función. Tengo una función que inicializa la estructura de datos. Algo como esto:

typedef void (*PFN_FOO)(int x, int y);

struct my_struct
{
    PFN_FOO pfn;
};

init_struct(struct my_struct *p, void *pfn)
{
    p->pfn = (PFN_FOO)pfn;
}

En Visual Studio y GCC este tipo de código se compila sin queja. De hecho, debido a que el argumento es de tipo pfn void * Realmente no necesito incluso poner un yeso allí; que sería sólo de forma implícita fundido sin queja.

En el Code Composer Studio para los chips DSP TI, consigo "aviso: no válido de conversión de tipo"

Mi política es hacer que el código compile sin advertencias, así que quiero arreglar esto. He intentado todo tipo de fundición. Descubrí que el compilador es perfectamente feliz si echo el puntero void * a int primero, y luego lanzarlo al tipo correcto. Ew, puaj!

¿Cómo puedo hacer este reparto sin el compilador se queja? ¿Realmente tengo para echar a int para cerrar el compilador?

Nota: Estoy específicamente no en busca de una solución para el efecto de "cambio init_struct() a aceptar un PFN_FOO en lugar de un void *". Eso funcionaría para este fragmento de código simplificado, pero no iba a funcionar para el código real, que crea una lista de cosas posiblemente heterogéneos.

¿Fue útil?

Solución

Estándar C específicamente no soporta conversiones entre punteros a objetos de datos y punteros a funciones. GCC y Visual Studio son compatibles con esta como una extensión.

Si desea hacer su función estándar conformes (pero todavía utilizar el parámetro void *), que podría pasar un puntero a un puntero de función en su lugar. Esto funciona porque la función punteros mismos son objetos ordinarios, por lo que un puntero a un puntero de función se puede convertir desde y hacia void * bien:

init_struct(struct my_struct *p, void *pfn)
{
    PFN_FOO *foo = pfn;
    p->pfn = *foo;
}

La persona que llama a continuación, debe crear un objeto PFN_FOO temporales para pasar un puntero a cuando se hace la llamada:

PFN_FOO fp = &somefunc;
/* ... */
init_struct(p, &fp);

Otros consejos

¿No debería escribir?

typedef void (*PFN_FOO)(int x, int y);

tutorial .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top