Passer et utiliser un nombre variable d’arguments pour fonctionner en C

Je ne comprends pas pourquoi cela n’imprime pas “Ceci est un test 42” comme je l’attendais?

1 #include  2 #include  3 4 #define ME(x) blah x 5 6 void blah(const char *fmt, ...) 7 { 8 va_list arg; 9 10 va_start(arg, fmt); 11 printf(fmt, arg); 12 va_end(arg); 13 } 14 15 int main() 16 { 17 ME(("this is a test %d\n", 42)); 18 19 return 0; 20 } 

Au lieu de cela, c’est quelque chose comme ça:

 $ gcc blah.c $ ./a.out this is a test 1606416656 

Vous voulez appeler vprintf () au lieu de printf ().

Vous devriez utiliser va_arg pour obtenir la valeur réelle de l’argument. Va_start n’est qu’une initialisation de la variable arg. Arg est en fait un pointeur sur la valeur de la stack, ce n’est pas la valeur même.

La ligne suivante obtient la valeur réelle:

 int myvalue = va_arg(arg,int); 

Notez que je reçois un int et non un short, puisque les short sont automatiquement promus en int par le compilateur C.

EDIT: La réponse de Uli est également correcte. Si vous souhaitez transmettre plusieurs valeurs à printf, vous devez appeler vprintf au lieu de printf (l’appel de va_arg n’est pas nécessaire, car dans ce cas, vous ne connaissez pas le type exact des arguments).