Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
1753 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Argument variadique imbriqué

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Argument variadique imbriqué

n°2328064
Digaboy
Posté le 23-01-2019 à 16:09:51  profilanswer
 

Bonjour
 
Je cherche à faire un appel de fonction à paramètre variable à plusieurs niveaux.
Un exemple sera plus parlant

Code :
  1. //On a les 2 prototypes suivants
  2. void debug_log_screen(char* str_fmt, ...);
  3. void debug_log_rtt(char* str_fmt, ...);
  4. //Et on a une fonction plus générique
  5. void debug_log(char* str_fmt, ...)
  6. {
  7.     #ifdef DEBUG_OUPTPUT_RTT
  8.     debug_log_rtt(????);
  9.     #endif
  10.     #ifdef DEBUG_OUTPUT_SCREEN
  11.     debug_log_screen (????);
  12.     #endif
  13. }


 
La question est de savoir comment je passe ma liste d'argument  
Je pourrais passer par un type va_list mais ça rend la fonction moins lisible je trouve

Message cité 1 fois
Message édité par Digaboy le 23-01-2019 à 16:11:20
mood
Publicité
Posté le 23-01-2019 à 16:09:51  profilanswer
 

n°2328065
Anonymouse
Posté le 23-01-2019 à 16:20:37  profilanswer
 

Digaboy a écrit :

Bonjour
 
Je cherche à faire un appel de fonction à paramètre variable à plusieurs niveaux.
Un exemple sera plus parlant

Code :
  1. //On a les 2 prototypes suivants
  2. void debug_log_screen(char* str_fmt, ...);
  3. void debug_log_rtt(char* str_fmt, ...);
  4. //Et on a une fonction plus générique
  5. void debug_log(char* str_fmt, ...)
  6. {
  7.     #ifdef DEBUG_OUPTPUT_RTT
  8.     debug_log_rtt(????);
  9.     #endif
  10.     #ifdef DEBUG_OUTPUT_SCREEN
  11.     debug_log_screen (????);
  12.     #endif
  13. }


 
La question est de savoir comment je passe ma liste d'argument  
Je pourrais passer par un type va_list mais ça rend la fonction moins lisible je trouve


 
Tu passe un va_list et tu crée un wrapper si elle peuvent être appelées directement. Comme le fait printf http://manpagesfr.free.fr/man/man3/printf.3.html

n°2328108
Digaboy
Posté le 24-01-2019 à 10:34:58  profilanswer
 

elles peuvent en effet être appelé directement et je ne peux donc pas changer leurs prototypes (pour le moment, la joie du legacy)
 
par contre je ne comprend pas ton histoire de wrapper. Je ne vois pas comment je peux créer mon wrapper qui va appeler mes fonctions de debug
 
edit: après avoir réfléchi un peu tu veux p-e dire de faire le wrapper dans l'autre sens, i.e. modifier la fonction de base  

Code :
  1. //On crée les wrappers
  2. void debug_wrap_log_screen(va_list arg_list);
  3. void debug_log_screen(char* str_fmt, ...)
  4. {
  5.     va_list arg_list;
  6.     va_start(arg_list, str_fmt);
  7.     debug_wrap_log_screen(arg_list);
  8.     va_end(arg_list);
  9. }
  10. //Et on a une fonction plus générique
  11. void debug_log(char* str_fmt, ...)
  12. {
  13.     va_list arg_list;
  14.     va_start(arg_list, str_fmt);
  15.     #ifdef DEBUG_OUPTPUT_RTT
  16.     debug_wrap_log_rtt(arg_list);
  17.     #endif
  18.     #ifdef DEBUG_OUTPUT_SCREEN
  19.     debug_wrap_log_screen(arg_list);   
  20.     #endif
  21.     va_end(arg_list);
  22. }


 
mais ça me fait modifier la fonction legacy


Message édité par Digaboy le 24-01-2019 à 11:17:44
n°2333406
rat de com​bat
attention rongeur méchant!
Posté le 11-05-2019 à 17:17:33  profilanswer
 

(Je sais ça date mais la question est intéressante.)

 

DEBUG_OUPTPUT_RTT et DEBUG_OUPTPUT_SCREEN sont exclusifs et debug_log() ne fait rien d'autre que renvoyer vers une des deux fonctions? Dans ce cas on pourrait passer par un pointeur de fonction non?

 
Code :
  1. void debug_log_screen(char* str_fmt, ...);
  2. void debug_log_rtt(char* str_fmt, ...);
  3. #define DEBUG_OUTPUT_SCREEN
  4. #ifdef DEBUG_OUPTPUT_RTT
  5. void (*debug_log)(char*, ...)=*debug_log_rtt;
  6. #endif
  7. #ifdef DEBUG_OUTPUT_SCREEN
  8. void (*debug_log)(char*, ...)=*debug_log_screen;
  9. #endif


Si mes supposition sont fausses alors ça ne marche pas bien sûr. :o


Message édité par rat de combat le 11-05-2019 à 17:18:56
n°2333408
rat de com​bat
attention rongeur méchant!
Posté le 11-05-2019 à 17:37:54  profilanswer
 

Sinon j'arrive à ceci. Ca compile sans warnings et dans mon test ça marche, mais est-ce que c'est fiable et respecte le standard??

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. void debug_log_screen(char * str_fmt, ...) //prototype fixe
  5. {
  6. //juste pour test supposons int, int et on s'en fout de l'ordre d'exécution des paramètres de printf()
  7. va_list ap;
  8. va_start(ap, str_fmt);
  9. printf("%s %d %d\n", str_fmt, va_arg(ap, int), va_arg(ap, int));
  10. va_end(ap);
  11. }
  12. void debug_log(char* str_fmt, ...) //fonction à faire
  13. {
  14. va_list ap;
  15. va_start(ap, str_fmt);
  16. debug_log_screen(str_fmt, *ap);
  17. va_end(ap);
  18. }
  19. int main(void)
  20. {
  21. debug_log("test", 1, 2);
  22. return 0;
  23. }

Message cité 2 fois
Message édité par rat de combat le 11-05-2019 à 17:39:40
n°2334363
rat de com​bat
attention rongeur méchant!
Posté le 02-06-2019 à 18:50:34  profilanswer
 

Personne pour me dire si ce bricolage respecte le standard? :o

n°2334694
Digaboy
Posté le 05-06-2019 à 22:31:10  profilanswer
 

désolé j'étais passé complètement à coté de ta réponse.
 
Je jette un oeil demain pour voir ce que ça donne

n°2334822
Digaboy
Posté le 07-06-2019 à 15:00:15  profilanswer
 

rat de combat a écrit :

Sinon j'arrive à ceci. Ca compile sans warnings et dans mon test ça marche, mais est-ce que c'est fiable et respecte le standard??

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. void debug_log_screen(char * str_fmt, ...) //prototype fixe
  5. {
  6. //juste pour test supposons int, int et on s'en fout de l'ordre d'exécution des paramètres de printf()
  7. va_list ap;
  8. va_start(ap, str_fmt);
  9. printf("%s %d %d\n", str_fmt, va_arg(ap, int), va_arg(ap, int));
  10. va_end(ap);
  11. }
  12. void debug_log(char* str_fmt, ...) //fonction à faire
  13. {
  14. va_list ap;
  15. va_start(ap, str_fmt);
  16. debug_log_screen(str_fmt, *ap);
  17. va_end(ap);
  18. }
  19. int main(void)
  20. {
  21. debug_log("test", 1, 2);
  22. return 0;
  23. }



 
Bon ça compile pas chez moi ^^
bon après je compile avec un compilo arm-gcc donc ya p-e une subtilité  

n°2334826
Digaboy
Posté le 07-06-2019 à 15:13:10  profilanswer
 

rat de combat a écrit :

Sinon j'arrive à ceci. Ca compile sans warnings et dans mon test ça marche, mais est-ce que c'est fiable et respecte le standard??

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. void debug_log_screen(char * str_fmt, ...) //prototype fixe
  5. {
  6. //juste pour test supposons int, int et on s'en fout de l'ordre d'exécution des paramètres de printf()
  7. va_list ap;
  8. va_start(ap, str_fmt);
  9. printf("%s %d %d\n", str_fmt, va_arg(ap, int), va_arg(ap, int));
  10. va_end(ap);
  11. }
  12. void debug_log(char* str_fmt, ...) //fonction à faire
  13. {
  14. va_list ap;
  15. va_start(ap, str_fmt);
  16. debug_log_screen(str_fmt, *ap);
  17. va_end(ap);
  18. }
  19. int main(void)
  20. {
  21. debug_log("test", 1, 2);
  22. return 0;
  23. }



 
Bon ça compile pas chez moi ^^  

error: invalid type argument of unary '*' (have 'va_list {aka __va_list}')


bon après je compile avec un compilo arm-gcc donc ya p-e une subtilité  
par contre la méthode du pointeur marche  
 
c'est dommage que la version du dessus ne fonctionne pas car ça aurait permit de passer la liste variable et d'ajouter des paramètres avant

n°2334841
rat de com​bat
attention rongeur méchant!
Posté le 07-06-2019 à 17:08:29  profilanswer
 

Tu as bien rajouté <stdarg.h>?
 
Chez moi ça compile sans warnings.

$ gcc --version
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516


 :??:


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Argument variadique imbriqué

 

Sujets relatifs
[Powershell] recuperer un argumentfonction Si imbrique exel
Comment écrire une donnée dans une cellule passée en argument ?Passage d'une structure en argument de fonction
passer une liste en argumentProblème argument fonction slope (vba)
Passer "un" argument "deux-en-un" a une fonction[XML] Envoyer en argument de script des valeurs du journal d'evenement
Faire une boucle avec un argument du tableau et définir si args=nombreredirection comme argument pour un exe
Plus de sujets relatifs à : Argument variadique imbriqué


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR