Aviso ao caçar tipo de tipo entre ponteiro e ponteiro para função
Pergunta
Estou portando algum código C para um ambiente de chip Ti DSP. Estou lutando com o compilador C.
Eu tenho uma estrutura de dados que inclui um ponteiro para uma função. Eu tenho uma função que inicializa a estrutura de dados. Algo assim:
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;
}
Sob Visual Studio e GCC, esse tipo de código compila sem reclamação. De fato, porque o pfn
argumento é tipo void *
Eu realmente não preciso nem colocar um elenco lá; Apenas lançaria implicitamente sem reclamar.
No Code Composer Studio para os chips Ti DSP, recebo "Aviso: Conversão do tipo inválido"
Minha política é fazer meu código compilar sem avisos, então quero consertar isso. Eu tentei todo tipo de elenco. Eu descobri que o compilador está perfeitamente feliz se eu lançar meu void *
ponteiro para int
Primeiro, e depois lançá -lo para o tipo correto. Ew, eca!
Como posso fazer esse elenco sem o compilador reclamando? Eu realmente tenho que lançar para int
para calar a boca o compilador?
Nota: eu sou especificamente não Procurando uma solução para o efeito de "mudança init_struct()
aceitar um PFN_FOO
em vez de um void *
"Isso funcionaria para esse trecho de código simplificado, mas não funcionaria para o código real, que cria uma lista de coisas possivelmente heterogêneas.
Solução
O padrão C especificamente não suporta conversões entre ponteiros para objetos de dados e ponteiros para funções. O GCC e o Visual Studio suportam isso como uma extensão.
Se você deseja fazer sua função conforme a conformidade (mas ainda use o void *
parâmetro), você pode passar um ponteiro para um ponteiro de função. Isso funciona porque os próprios ponteiros de função são objetos comuns, portanto um ponteiro para um ponteiro de função pode ser convertido para e de void *
bem:
init_struct(struct my_struct *p, void *pfn)
{
PFN_FOO *foo = pfn;
p->pfn = *foo;
}
O chamador deve então criar um temporário PFN_FOO
Objeto de passar um ponteiro para quando fizer a chamada:
PFN_FOO fp = &somefunc;
/* ... */
init_struct(p, &fp);
Outras dicas