Pointeurs de fonctions avec "..."

Pointeurs de fonctions avec "..." - C - Programmation

Marsh Posté le 14-06-2007 à 16:22:18    

Bonjour,

 

je voudrais déclarer un pointeur de fonction vers une autre. Pourquoi ai-je un warning lorsque je fais :

 
Code :
  1. int toto(int a, int b); //une fonction déclarée en prototype;
  2. int main() {
  3.   int (*f) (int a, ...) = toto;
  4. return 0;
  5. }



warning: assignment from incompatible pointer type


dumoins est-ce valide ? N'est il pas possible de déclarer un pointeurs vers une fonction avec nombre variable d'argument vers une fonctions avec un nombre prédéfini d'arguments ?

 

merci par avance  :jap:


Message édité par in_your_phion le 14-06-2007 à 16:23:23
Reply

Marsh Posté le 14-06-2007 à 16:22:18   

Reply

Marsh Posté le 14-06-2007 à 16:43:58    

non. et tu cherches à faire quoi d'ailleurs ?

Reply

Marsh Posté le 14-06-2007 à 16:44:37    

c'est possible parceque je l'ai fais en son temps, mais ca fait un bail que je n'ai plus codé en c.
 
ceci dit j'essaierai plutot
 

Code :
  1. int (*f) (int a, ...) = &toto;

Reply

Marsh Posté le 14-06-2007 à 16:51:55    

Taz a écrit :

non. et tu cherches à faire quoi d'ailleurs ?

 

je cherche à faire ca. Un pointeur de fonction qui pointe vers n'importe quel type de fonction, ou plus précisemment des fonctions dont le nombres d'argument n'est pas le même et qui ont pour premier argument un int. Ca marche si je fais :

 
Code :
  1. int toto(int a, int b); //une fonction déclarée en prototype;
  2.       int main() {
  3.       int (*f) (int a, ...) = (void*)toto;
  4.       return 0;
  5.       }
 

est-ce envisageable ?


Message édité par in_your_phion le 14-06-2007 à 16:59:20
Reply

Marsh Posté le 14-06-2007 à 16:59:28    

et après tu utilises comment ...

Reply

Marsh Posté le 14-06-2007 à 17:06:38    

Taz a écrit :

et après tu utilises comment ...

 

par exemple (exemple bidon mais bon) :

 
Code :
  1. void ma_fonction_bidon(int a, void (*f)(int b, ...) ) :
  2. void toto_1(int a); // fonction qui fait un truc avec a
  3. void toto_2(int a, int b); //fonction qui fait un truc avec a et b
  4. int main() {
  5.       void (*f)(int a, ...) = (void*)toto_1;
  6.       ma_fonction_bidon(10, f);
  7.  
  8. return 0;
  9. }
  10. void ma_fonction_bidon(int a, void (*f)(int b, ...) ) {
  11. int nombre_de_parametres,b;
  12.    /* normalement on est censé récupérer les arguments avec la librairie stdarg ??? enfin j'imagine  ... gloups */
  13. if (nombre_de_parametres == 1)
  14.         f(a);
  15.  
  16.   if (nombre_de_parametres == 2)
  17.       f(a,b); //b a été récupéré à l'aide de va_list, etc
  18. }


[:laimuh]


Message édité par in_your_phion le 14-06-2007 à 17:07:32
Reply

Marsh Posté le 14-06-2007 à 17:24:30    

bah t'imagines ...
 
t'as un problème de design, pas de code

Reply

Marsh Posté le 14-06-2007 à 17:27:38    

pointer vers des fonctions dont le nombre des arguments n'est pas le même la je ne pense pas que ce soit possible, on peut s'inspirer de la programmation objet et surcharger une fonction, mais la définition de ta fonction doit être la même. donc tu devras avoir le même nombre d'arguments, ou alors tu fais passer tes arguments via un tableau de pointeur et tu ne passe que le tableau en paramètre.

Reply

Marsh Posté le 14-06-2007 à 17:29:15    

ok ok ...Merci :) mais en théorie c'est possible ? je veux dire, mon truc marche non ? Imaginons que les fonctions sont déja la et que je peux pas y toucher, comment faire ??


Message édité par in_your_phion le 14-06-2007 à 17:29:55
Reply

Marsh Posté le 14-06-2007 à 17:33:52    

tel quel je ne pense pas, parceque si tu regardes la définition de f dans ta fonction bidon tu verras que tu as défini le nombre d'argument, donc déja la tu ne passeras pas la compilation je pense.

Reply

Marsh Posté le 14-06-2007 à 17:33:52   

Reply

Marsh Posté le 14-06-2007 à 17:49:44    

casimimir a écrit :

tel quel je ne pense pas, parceque si tu regardes la définition de f dans ta fonction bidon tu verras que tu as défini le nombre d'argument, donc déja la tu ne passeras pas la compilation je pense.


 
ben ca à l'air de marcher chez moi, par contre c'est vrai qu'il faut que je passe la liste des arguments dans la fonction ma_fonction_bidon

Reply

Marsh Posté le 14-06-2007 à 18:05:57    

in_your_phion a écrit :

ben ca à l'air de marcher chez moi, par contre c'est vrai qu'il faut que je passe la liste des arguments dans la fonction ma_fonction_bidon


 
Tu peux essayer avec les va_arg qui vont directement pointer là où se trouvent les arguments mais
1) ce n'est pas portable
2) ce n'est pas évident
3) ce n'est pas portable (tiens, je l'ai déjà dit)
4) c'est moche
 
Pour les fonctions, il y a un grand principe à connaître qui est la notion de "signature" (ce qui identifie une fonction). Et une fonction est identifiée par son nom, le nombre de ses arguments et leur type.
 
Sinon j'aime bien ta façon de chercher plein de trucs. Mais comme pour tout langage, il y a des limites. Par exemple ne vient pas nous demander si tu peux créer une fonction nommée "extern()" ou bien comment faire pour appeler la fonction "main()" depuis une fonction infèrieure... :pt1cable:


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 14-06-2007 à 18:13:33    

Sve@r a écrit :

Tu peux essayer avec les va_arg qui vont directement pointer là où se trouvent les arguments mais
1) ce n'est pas portable
2) ce n'est pas évident
3) ce n'est pas portable (tiens, je l'ai déjà dit)
4) c'est moche

 

Pour les fonctions, il y a un grand principe à connaître qui est la notion de "signature" (ce qui identifie une fonction). Et une fonction est identifiée par son nom, le nombre de ses arguments et leur type.

 

Sinon j'aime bien ta façon de chercher plein de trucs. Mais comme pour tout langage, il y a des limites. Par exemple ne vient pas nous demander si tu peux créer une fonction nommée "extern()" ou bien comment faire pour appeler la fonction "main()" depuis une fonction infèrieure... :pt1cable:

 

salut
oui je suis d'accord c'est très très moche ... je voulais savoir si en théorie je peux le faire, même si je le ferai pas car c'est mal (c'est mal :o). Y'aurait-il une solution néanmoins si on souhaite exploiter des fonctions "à la volée", que celles ci soient déja disponible (donc pas possible de changer de protoype, etc), et qu'elles n'aient pas le meme nombre d'arguments ? [:dawa ]

 

ps: comment fais-ton pour créer une fonction extern qui appelle la fonction main ?  :o


Message édité par in_your_phion le 14-06-2007 à 18:14:46
Reply

Marsh Posté le 15-06-2007 à 08:15:32    

Oui tu peux le faire, et d'ailleurs tu n'es même pas obligé de mettre des "...". Le fait de mettre des "..." ne rend pas la chose plus propre.

Reply

Marsh Posté le 15-06-2007 à 09:54:16    

matafan a écrit :

Oui tu peux le faire, et d'ailleurs tu n'es même pas obligé de mettre des "...". Le fait de mettre des "..." ne rend pas la chose plus propre.


 
salut
comment faire alors ? Je mettais des "..." car le nombre de paramètres varie d'une fonction à l'autre...

Reply

Marsh Posté le 15-06-2007 à 11:06:07    

Tu ne met rien : void (*f)()

Reply

Marsh Posté le 15-06-2007 à 11:11:51    

matafan a écrit :

Tu ne met rien : void (*f)()

 

:ouch:

 

c'est possible ça ?? Mais comment se fesse ?????? Comment se fesse faice que l'on puisse déclarer un pointeur de fonctions sans paramètres et lui passer une adresse qui pointe vers une fonction de 1 ou plus paramètres??!!? C'est une hérésie, non ? Pourtant ceci marche :

Code :
  1. void toto(int a, int b, int c);
  2. void god_function(int a, void (*f)() );
  3. int main() {
  4. god_function(110,toto);
  5. return 0
  6. }
 

oO, mais pourquoi donc comment qu'est-ce ainsi d'ou quoi ? Dans ce cas quel intéret de déclarer un void (*f) (void *a, void *b); dans certains cas, plutot qu'un void (*f)() ??  :heink:

Message cité 1 fois
Message édité par in_your_phion le 15-06-2007 à 11:19:33
Reply

Marsh Posté le 15-06-2007 à 11:39:01    

(*f)() veut dire qu'on ne dit rien sur les arguments de f, pas que f ne prend pas d'arguments (qui s'écrirait (*f)(void)).

Reply

Marsh Posté le 15-06-2007 à 11:48:00    

matafan a écrit :

(*f)() veut dire qu'on ne dit rien sur les arguments de f, pas que f ne prend pas d'arguments (qui s'écrirait (*f)(void)).


 
ok :sweat: ... alors dans ce cas à quoi sert la notation "..." ??

Reply

Marsh Posté le 15-06-2007 à 12:10:26    

pense à fprintf

Reply

Marsh Posté le 15-06-2007 à 12:19:48    

Taz a écrit :

pense à fprintf


 
mais dans ce cas pourquoi le prototype n'est pas int fprintf(); ?

Reply

Marsh Posté le 15-06-2007 à 12:36:08    

Non mais les "()" ça ne marche que pour les déclarations. Quand tu définies ta fonction il faut évidemment donner tous les arguments. D'où l'utilité des "..." par définir des fonctions à arguments variables.

Reply

Marsh Posté le 15-06-2007 à 12:39:48    

matafan a écrit :

Non mais les "()" ça ne marche que pour les déclarations. Quand tu définies ta fonction il faut évidemment donner tous les arguments. D'où l'utilité des "..." par définir des fonctions à arguments variables.

 

je ne suis pas sûr de comprendre ... mon exemple ci dessus marche mais je n'ai pas utilisé la notation ..., ou faudrais-je que je l'utilise ? comment faire pour passer la liste d'arguments ? Avec un void * ? Et si les arguements ne sont pas tous de meme type

 

au fait merci pour votre aide  :love:  :love:


Message édité par in_your_phion le 15-06-2007 à 12:39:59
Reply

Marsh Posté le 15-06-2007 à 12:53:54    

Dans ce cas tu n'as pas à utiliser la notation "..." car tu n'as pas de fonction à arguments variable. Tu as juste une fonction normale (toto) et un pointeur de fonction (f), qui peut ponter vers des fonctions ayant un nombre quelconque d'arguments.
 
Tu aurais besoin des "..." si ta fonction toto prenait elle-même un nombre variable d'arguments. Dans ce cas tu utiliserais les va_args dans toto. Mais même dans ce cas tu n'aurais toujours pas besoin des mettre des "..." dans la déclaration de f.

Reply

Marsh Posté le 15-06-2007 à 13:32:27    

matafan a écrit :

Dans ce cas tu n'as pas à utiliser la notation "..." car tu n'as pas de fonction à arguments variable. Tu as juste une fonction normale (toto) et un pointeur de fonction (f), qui peut ponter vers des fonctions ayant un nombre quelconque d'arguments.

 

Tu aurais besoin des "..." si ta fonction toto prenait elle-même un nombre variable d'arguments. Dans ce cas tu utiliserais les va_args dans toto. Mais même dans ce cas tu n'aurais toujours pas besoin des mettre des "..." dans la déclaration de f.

 

ok .... donc ca ne sert à rien alors "...", c'est juste un truc de notation ??

 


edit : j'aurais une autre question s'iouplé ....Est t'il possible d'accéder à la table des arguments d'une fonction ? Par exemple, imaginons que je suis dans le cas ou j'ai une fonction qui est de prototype :

 
Code :
  1. void ma_fonction_generique(void (*f)() , void * params );
 

donc, je lui envoie un pointeur de fonction, et params, qui est un tableau qui regroupe la liste des paramètres. Par exemple, params[0] donne le nombre d'arguments et apres, la suite du tableau sont les arguments effectifs. Par exemple :

 
Code :
  1. int params[] = {3,1,2,3};
 


mettons que je passe params et une fontion toto(int, int, int) à la fontcion ma_fonction_generique(). Comment faire pour récuperer dynamiquement les arguments de params et les mettre dans toto ? Y'aurait-il un truc du genre :

 
Code :
  1. void ma_fonction_generique(void (*f)() , void * params ) {
  2. /* comment mettre de manière dynamique les valeurs de params dans f ? */
  3. f.parametre1 = (int)params[1];
  4. f.parametre2 = (int)params[2];
  5. f.parametre3 = (int)params[3];
  6. //reste du code
  7. }
 


merci par avance :)


Message édité par in_your_phion le 15-06-2007 à 14:56:27
Reply

Marsh Posté le 15-06-2007 à 16:55:49    

A part un gros switch bien dégueu sur le nombre de paramètres, je ne vois pas. Du coup ça limite vachement l'intérêt du callback.

Reply

Marsh Posté le 15-06-2007 à 17:00:24    

matafan a écrit :

A part un gros switch bien dégueu sur le nombre de paramètres, je ne vois pas. Du coup ça limite vachement l'intérêt du callback.


 
 :cry:  
 
... un switch bien dégueu serait donc la meilleure solution (et la seule) ??
 
 :cry:

Reply

Marsh Posté le 15-06-2007 à 17:25:28    

Non, la meilleurs solution c'est de faire ton truc différemment. Tes fonctions f devraient elles aussi prendre un tableau params en paramètre. Ou alors un va_list.

Reply

Marsh Posté le 15-06-2007 à 17:34:29    

in_your_phion a écrit :

Comment se fesse faice ...


Comment se fait-ce ...  :o  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 16-06-2007 à 13:57:24    

Reply

Marsh Posté le 17-06-2007 à 09:47:38    

Taz a écrit :

bah t'imagines ...
 
t'as un problème de design, pas de code


+1  
 
in_your_phion:
Tu pourrais pas nous en dire plus sur ton vrai probleme ... qu'on t'aide a trouver une vraie solution?
 

Reply

Marsh Posté le 18-06-2007 à 00:28:40    

 

merci en fait c'est ca que je veux faire :jap: Je veux juste savoir comment on fait pour passer une fonction "générique". Dans cet exemple les arguments sont tous de même type. Comment pourais t-on faire s'il ne sont pas de même type ?

 

merci  :jap:


Message édité par in_your_phion le 18-06-2007 à 00:29:02
Reply

Marsh Posté le 18-06-2007 à 03:54:26    

__builtin_apply & consorts permet juste de trampoliner un peu plus proprement, le tripotage des arguments est dehors de sa juridiction. J'ai des doutes sur le bien fondé de votre choix de cette approche si vous ne saisissez pas le pourquoi.

Reply

Marsh Posté le 18-06-2007 à 09:31:47    

tbp a écrit :

__builtin_apply & consorts permet juste de trampoliner un peu plus proprement, le tripotage des arguments est dehors de sa juridiction. J'ai des doutes sur le bien fondé de votre choix de cette approche si vous ne saisissez pas le pourquoi.


 
c'est un exercice ...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed