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.

Foi útil?

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

Você não deveria escrever?

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

Veja isso tutorial.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top