Argument variadique imbriqué

Argument variadique imbriqué - C - Programmation

Marsh Posté le 23-01-2019 à 16:09:51    

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
Reply

Marsh Posté le 23-01-2019 à 16:09:51   

Reply

Marsh Posté le 23-01-2019 à 16:20:37    

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

Reply

Marsh Posté le 24-01-2019 à 10:34:58    

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
Reply

Marsh Posté le 11-05-2019 à 17:17:33    

(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
Reply

Marsh Posté le 11-05-2019 à 17:37:54    

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
Reply

Marsh Posté le 02-06-2019 à 18:50:34    

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

Reply

Marsh Posté le 05-06-2019 à 22:31:10    

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

Reply

Marsh Posté le 07-06-2019 à 15:00:15    

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é  

Reply

Marsh Posté le 07-06-2019 à 15:13:10    

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

Reply

Marsh Posté le 07-06-2019 à 17:08:29    

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


 :??:

Reply

Sujets relatifs:

Leave a Replay

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