Gå til innhold

Problem med typedef til funksjonspeker


Anbefalte innlegg

Jeg prøver å lage en typedef som skal hete callback_t. Typen skal være en peker til en funksjon som er deklarert sånn:

int navn_her (int aParam, int bParam, int cParam, int dParam, unsigned int sender, callback_t sender);

Altså, den er kompatibel med callback_t og tar en callback_t som siste parameter.

 

Jeg har prøvd dette:

typedef int (* callback_t) (int aParam, int bParam, int cParam, int dParam, unsigned int sender, callback_t callback);

 

Når jeg kompilerer får jeg følgende feilmelding:

error: expected declaration specifiers or '...' before 'callback_t'

 

Går det ikke an å få til noe sånt i C?

Endret av tsg1zzn
Lenke til kommentar
Videoannonse
Annonse

Det er kanskje ikke det mest elegante, men jeg tror noe slikt skulle fungere:

typedef int (* callback_t) (int, int, int, int, unsigned int, void*);

int foo(int a, int b, int c, int d, unsigned int e, void* fptr)
{
callback_t p = (callback_t)fptr;
printf("ayo!");
}

int main()
{
callback_t ptr = foo;
ptr(1, 2, 3, 4, 5, ptr);
}

Lenke til kommentar
typedef int (*CompareFunc)(int a, int b);

int compare(int a, int b, CompareFunc compirator)
{
return (*compirator)(a, b);
}

int min(int a, int b)
{
return a < b ? a : b;
}

int max(int a, int b)
{
return a > b ? a : b;
}

int main()
{
int a = 5;
int b = 7;

printf("Min of %d and %d is %d\n", a, b, compare(a, b, min));
printf("Max of %d and %d is %d\n", a, b, compare(a, b, max));

return 0;
}

Lenke til kommentar
Det er kanskje ikke det mest elegante, men jeg tror noe slikt skulle fungere:

typedef int (* callback_t) (int, int, int, int, unsigned int, void*);

int foo(int a, int b, int c, int d, unsigned int e, void* fptr)
{
callback_t p = (callback_t)fptr;
printf("ayo!");
}

int main()
{
callback_t ptr = foo;
ptr(1, 2, 3, 4, 5, ptr);
}

 

Nei, det skal ikke fungere -- den *eneste* pekeren som void* ikke kan holde er en funksjonspeker (det er bl.a. derfor det er skikkelig pes å skrive en generisk heterogen container i C).

 

Det til side, alle funksjonspekere er kompatible seg imellom, men å lage en slik rekursiv typedef er nok ikke mulig i C. Det enkleste er kanskje:

 

typedef int (*fptr_t)(int (*)());

 

... kalle en funksjon gjennom en peker av typen fptr_t med en funksjonspeker som argument som typecastes til rett type (herregud det ble en uleselig setning).

Endret av zotbar1234
Lenke til kommentar
Hmm, daså. Det fungerer når jeg prøver det her, men det er godt mulig at det egentlig ikke skal fungere som du sier, og at det bare er GCC som velger å være grei, heh.

 

ISO/IEC 9899:1999, 6.3.2.3, §1: 1 A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

 

Litt senere, §8: A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer.

 

Jeg er faktisk litt usikker på hva som er begrunnelsen for dette. Kanskje for å gjøre GC lettere? (funksjonspekere trenger aldri å betraktes av en GC). Kanskje fordi at funksjonspekere skal kunne ha annen informasjon i seg enn bare funksjonsadressen? Uansett void* og en funksjonspeker er ikke kompatible. Selv med typecast.

Lenke til kommentar

Mulig det er noe jeg har misforstått her, men jeg ser ikke hvorfor void* ikke kan konverteres til funksjonspekere ut i fra dette. En funksjonspeker blir vel å regne som en "object type"? Paragrafen som forteller spesifikt rundt funksjonspekere sier jo heller ikke at en funksjonspeker ikke kan konverteres til en void-peker.

Lenke til kommentar
Mulig det er noe jeg har misforstått her, men jeg ser ikke hvorfor void* ikke kan konverteres til funksjonspekere ut i fra dette.

 

Fordi det er alle konverteringene som en void* kan delta i.

 

En funksjonspeker blir vel å regne som en "object type"?

 

En funksjonspeker, ja, men standarden er ganske klar på at en funksjonstype er forskjellig fra en object type -- 6.2.5, §1 "Types are partitioned into object types (...), function types (...), and incomplete types". En void* kan konverteres til en vilkårlig T*, der T er en object type, men siden funksjonstype ikke er en object type, kan ikke en void* konverteres til en funksjonspeker.

 

Paragrafen som forteller spesifikt rundt funksjonspekere sier jo heller ikke at en funksjonspeker ikke kan konverteres til en void-peker.

 

6.3.2.3 forteller hvilke konverteringer er/skal være lovlige. Alt det andre er utenfor standarden, selv om det kan godtas av en spesifikk implementasjon.

Lenke til kommentar
Mulig det er noe jeg har misforstått her, men jeg ser ikke hvorfor void* ikke kan konverteres til funksjonspekere ut i fra dette.

 

Fordi det er alle konverteringene som en void* kan delta i.

 

En funksjonspeker blir vel å regne som en "object type"?

 

En funksjonspeker, ja, men standarden er ganske klar på at en funksjonstype er forskjellig fra en object type -- 6.2.5, §1 "Types are partitioned into object types (...), function types (...), and incomplete types". En void* kan konverteres til en vilkårlig T*, der T er en object type, men siden funksjonstype ikke er en object type, kan ikke en void* konverteres til en funksjonspeker.

 

Paragrafen som forteller spesifikt rundt funksjonspekere sier jo heller ikke at en funksjonspeker ikke kan konverteres til en void-peker.

 

6.3.2.3 forteller hvilke konverteringer er/skal være lovlige. Alt det andre er utenfor standarden, selv om det kan godtas av en spesifikk implementasjon.

Ah, det tenkte jeg ikke på. Da er jeg med. :)

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...