2012-03-04 2 views
4

J'ai le code suivant:Afficher un long pointeur de fonction?

long fp = ... 
void (*ptr)(long, char*, char*) = fp; 

La longue fp est un pointeur de fonction correcte, qui vient en tant de temps. J'obtiens l'avertissement standard "fait pointer de int sans cast". Je veux être capable de compiler avec:

-std=iso9899:1990 -pedantic-errors 

qui transforme cet avertissement en erreur. La question est: quel est le bon casting? J'ai essayé diverses suppositions, par exemple:

void (*ptr)(long, char*, char*) = (void)(*)(long, char*, char*) fp; 

Mais ne peux pas sembler trouver le bon.

+0

Pourquoi voudriez-vous faire cela? –

+0

Pourquoi voudrais-je faire quoi? – gubby

+0

Fusion entre entiers et pointeurs de fonction? –

Répondre

7

Le casting "correct" est:

void (*ptr)(long, char*, char*) = (void (*)(long, char*, char*))fp; 

De toute évidence, cela peut être rangea avec un typedef approprié.

Mais dans les deux cas, le résultat est défini par l'implémentation. Si vous le pouvez, évitez ceci, et maintenez le pointeur dans un type de pointeur. La meilleure chose serait d'utiliser intptr_t si elle est disponible.

+0

@KerrekSB: Dans quel sens? –

+0

Non, tant pis, c'est bon! –

7

C'est probablement quelque chose comme:

void (* ptr)(long, char, char *) = (void (*)(long, char, char *))fp; 

mais ma suggestion est d'utiliser un typedef et oublier tout ce gâchis:

typedef void (* fnPtr)(long, char, char*); 
fnPtr ptr = (fnPtr) fp; 
+0

oui, en utilisant un typedef est le bon chemin à parcourir – slashmais

4

La seule façon « correcte » est de ne pas jeter tout , mais copiez plutôt la représentation binaire:

long fp; 
void (*ptr)(long, char*, char*); 

memcpy(&ptr, &fp, sizeof ptr); 
+0

Sauf qu'il échoue catastrophiquement lorsque sizeof (long)! = Sizeof (ptr). –

2

Le problème principal ici est que ANSI-C ne le permet pas, malgré les innombrables C-API basés sur cette fonctionnalité. Par conséquent, vous rencontrerez probablement des problèmes lors de la compilation avec -pedantic. Comme d'autres affiches l'ont laissé entendre, vous pouvez tricher autour de la distribution en utilisant des choses comme memcpy() ou un type d'union pour lancer. Par ailleurs, POSIX garantit que cela fonctionnera, de sorte que la partie concernant les 'résultats définis par l'implémentation' devient beaucoup moins effrayante.

+0

Merci pour le conseil. – gubby

+0

C99 le permet explicitement, il indique simplement que les résultats sont définis par l'implémentation. –

+0

Cool, je ne le savais pas. Je suis surtout un gars C++, donc je suis plus familier avec C89, qui ne l'a pas permis. – ComicSansMS

Questions connexes