Nombre de parameters dans l’appel de la méthode d’argument de variable C

Lorsque vous utilisez va_start (), va_arg () et va_end () pour lire les parameters transmis à une méthode, existe-t-il un moyen de compter le nombre d’arguments?

Selon la page de manuel, si vous appelez va_arg () trop souvent, vous obtenez des “erreurs aléatoires”:

S’il n’y a pas d’argument suivant ou si le type n’est pas compatible avec le type de l’argument suivant (tel que promu en fonction des promotions d’argument par défaut), des erreurs aléatoires se produiront.

N ° une fonction d’argument variable (telle que printf ), doit “savoir” quand arrêter de chercher plus d’arguments.

printf connaît le nombre de %d , %s et d’autres symboles dans sa chaîne de format.

D’autres fonctions utilisent parfois les valeurs Sentinel:

 sumValues(1, 3, 5, 7, 6, 9, -1); // will add numbers until it encounters a -1 

D’autres fonctions peuvent avoir le nombre de parameters indiqué à l’avance:

 AddNames(4, "Bill", "Alice", "Mike", "Tom"); 

Voici un truc assez étonnant qui vous permet de construire ce que vous voulez en utilisant les macros variadiques de C99:

PP_NARG ()
Retourne le nombre d’arguments contenus dans __VA_ARGS__

Vous pouvez vous en servir pour écrire une macro qui enveloppe votre fonction réelle et qui ajoute un nombre au début de ses arguments.

Voir aussi cette question . Cependant, les approches classiques sont probablement encore plus sensées pendant encore un an ou trois!


Le code, pour que cette réponse soit utile même sans l’archive Usenet …

 /* The PP_NARG macro returns the number of arguments that have been * passed to it. */ #define PP_NARG(...) \ PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) #define PP_NARG_(...) \ PP_ARG_N(__VA_ARGS__) #define PP_ARG_N( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ _61,_62,_63,N,...) N #define PP_RSEQ_N() \ 63,62,61,60, \ 59,58,57,56,55,54,53,52,51,50, \ 49,48,47,46,45,44,43,42,41,40, \ 39,38,37,36,35,34,33,32,31,30, \ 29,28,27,26,25,24,23,22,21,20, \ 19,18,17,16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0 

Il y a deux façons de savoir combien d’arguments ont été passés. Tout d’abord, vous pouvez demander à l’un des parameters de la fonction (comme printf par exemple). L’autre méthode consiste à append une valeur sentinelle à la fin de votre liste. Par exemple, vous pouvez vous arrêter à un argument NULL .

Vous pouvez utiliser va_copy si vous choisissez la deuxième méthode, mais souhaitez quand même compter les parameters avant de décider quoi faire avec.