Salut a tous,
imaginons que je declare un fonction comme ceci
et lorsque j'appel ma fonctionCode:int mafonction(char *s, ...)
comment determiner qu'il y a deux argumentsCode:mafonction("test", "toto", "titi")
Version imprimable
Salut a tous,
imaginons que je declare un fonction comme ceci
et lorsque j'appel ma fonctionCode:int mafonction(char *s, ...)
comment determiner qu'il y a deux argumentsCode:mafonction("test", "toto", "titi")
On ne peut pas directement. Il faut envoyer le nombre d'arguments à la fonction, explicitement ou non (cf. le specificateur de format de printf()) ou se servir d'un argument "balise" pour signaler la fin des arguments (NULL, par exemple).
ça y ai je viens de réussir à utiliser un code que j'avais trouvé sur comp.std.c (il m'a fallu presque une année :aie:) :Citation:
Envoyé par DaZumba
Code:
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 #include <stdio.h> #include <stdarg.h> /* 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 #define FOO(...) foo (PP_NARG(__VA_ARGS__), __VA_ARGS__) static void foo (int nb, ...) { va_list ap; printf ("%d : ", nb); va_start (ap, nb); for (int i = 0; i < nb; i++) { char *x = va_arg (ap, char *); printf ("%s, ", x); } va_end (ap); printf ("\n"); } int main (void) { FOO ("test", "toto", "titi"); FOO ("test", "toto", "titi", "tata"); return 0; } /* Note: using PP_NARG() without arguments would violate 6.10.3p4 of ISO C99. */
Code:
1
2 3 : test, toto, titi, 4 : test, toto, titi, tata,
Je ne connais pas les limites en terme de portabilité de ce genre de chose :(
C99
Soit l'indication est dans le premier paramètre (c'est le mécanisme prévu par le langage C) :Citation:
Envoyé par Pitou5464
Code:mafonction(2, "toto", "titi")
etc. soit, puisqu'on a affaire à des pointeurs, tu peux marquer la fin de la liste avec NULL : Dans ce cas, le 1 er paramètre (qui est obligatoire), n'est pas utilisé :Code:mafonction("2", "toto", "titi")
ouCode:mafonction(0, "toto", "titi", (char*) NULL)
Nota : S'agissant d'une fonction variadic, le cast est obligatoire pour être portable.Code:mafonction(NULL, "toto", "titi", (char*) NULL)
Sinon, je crois qu'on peut s'amuser à analyser la pile "à la main", avec un bloc d'assembleur. Totalement pas portable :mouarf:
Il me faudrait des détails parce que je ne vois pas comment c'est possible en général (un système donné peut utiliser une ABI qui le rende possible, mais je ne suis même pas sûr que ce soit courant -- il ne me semble pas que ce soit possible avec les ABI que j'ai regardée mais je peux me tromper).Citation:
Envoyé par Gruik
Oui désolé, je dis des conneries, j'avais cru comprendre que c'était possible. On pourrait avoir la taille totale des paramètres passés, mais si on a pas leur type (la taille de leur type), ça sert à rien