2009-10-12 14 views
6

Estoy transfiriendo algunos códigos C a un entorno de chip DSP de TI. Estoy lidiando con el compilador de CAdvertencia cuando se realiza el cambio entre el puntero y el puntero a la función

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 quejarse. De hecho, debido a que el argumento pfn es tipo void *, realmente no necesito ni siquiera poner un molde allí; simplemente lanzaría implícitamente sin queja.

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

Mi política es hacer que el código compile sin advertencias, por lo que quiero arreglar esto. He intentado todo tipo de casting. Descubrí que el compilador está muy contento si lanzo mi puntero void * primero a int y luego lo echo al tipo correcto. Ew, ¡puaj!

¿Cómo puedo hacer este cast sin que el compilador se queje? ¿Realmente tengo que enviar a int para cerrar el compilador?

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

+0

¿No sería más simple tener el acuerdo de tipo correcto y hacer pfn tipo PFN_FOO? Otro punto: deberías darle a init_struct() un tipo explícito; eso no se compila sin advertencias en VC++ 2008 incluso utilizando la compilación C. – Clifford

+0

@Clifford, mi código real siempre tiene tipos explícitos en las funciones; Escribo mi código para compilar sin advertencias y soy cuidadoso con los tipos. El problema que estoy resolviendo es crear una función que inicialice una estructura de datos que pueda contener elementos heterogéneos, y quiero una única función de inicio, no una función de inicio por tipo de datos posible almacenados en ella. – steveha

Respuesta

12

El estándar C específicamente no admite conversiones entre punteros a objetos de datos y punteros a funciones. GCC y Visual Studio lo admiten como una extensión.

Si desea hacer que su función cumpla con la norma (pero aún use el parámetro void *), podría pasar un puntero a un puntero a la función. 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 debe entonces crear un PFN_FOO objeto temporal para pasar un puntero a cuando realiza la llamada:

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

Wow, estaba pensando que esto era algo de TI C, pero me estás diciendo que es una cosa estándar de C. Eso es muy útil. – steveha

+1

Bien, reescribí mi función para que en lugar de tomar 'void *', tome 'PFN', definido así:' typedef void (* PFN)(); 'Y ahora el código se compila sin previo aviso. Es suficiente que comience como un tipo de puntero para funcionar, antes de ser lanzado a un tipo específico de PFN. ¡Gracias! Respuesta aceptada y +1. – steveha

+0

Correcto, puede convertir libremente entre diferentes tipos de punteros de función. – caf

3

¿No debería escribir?

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

Ver esto tutorial.

+0

Er, sí. Lo tengo correcto en el código real, y voy a cambiar mi estúpido código de ejemplo para que sea correcto. Ahora, ¿tiene algún consejo sobre la pregunta real? – steveha

+0

Solo para aclarar: es posible que haya sospechado que el problema era que mi código no declaraba correctamente el tipo PFN_FOO. Ese no es el problema, y ​​el código realmente funciona bastante bien, pero el compilador TI DSP C me está dando advertencias. – steveha

+0

¿Está compilando como C o C++? – dirkgently

Cuestiones relacionadas