Emancipate Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 (endret) 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 23. februar 2009 av tsg1zzn Lenke til kommentar
Dead_Rabbit Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 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
Emancipate Skrevet 23. februar 2009 Forfatter Del Skrevet 23. februar 2009 Joda, det funker. Det er bare det at dette skal være en del av et API og da blir det litt uelegant å gjøre det sånn i tonnevis med foo-funksjoner. Lenke til kommentar
LostOblivion Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 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
LostOblivion Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 Ehem...er litt trøtt i kveld tror jeg. Lenke til kommentar
zotbar1234 Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 (endret) 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 23. februar 2009 av zotbar1234 Lenke til kommentar
Dead_Rabbit Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 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. Lenke til kommentar
zotbar1234 Skrevet 23. februar 2009 Del Skrevet 23. februar 2009 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
Dead_Rabbit Skrevet 24. februar 2009 Del Skrevet 24. februar 2009 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
zotbar1234 Skrevet 24. februar 2009 Del Skrevet 24. februar 2009 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
Emancipate Skrevet 24. februar 2009 Forfatter Del Skrevet 24. februar 2009 Det til side, alle funksjonspekere er kompatible seg imellom, men å lage en slik rekursiv typedef er nok ikke mulig i C.Grr, dess bedre jeg lærer C, dess mindre liker jeg det. Lenke til kommentar
Dead_Rabbit Skrevet 24. februar 2009 Del Skrevet 24. februar 2009 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
zotbar1234 Skrevet 25. februar 2009 Del Skrevet 25. februar 2009 (endret) Grr, dess bedre jeg lærer C, dess mindre liker jeg det. The C language combines all the power of assembly with all the ease-of-use of assembly. STR Endret 25. februar 2009 av zotbar1234 Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå