macro _INTSIZEOF (utilisée dans va_start et va_arg)
Bonjour.
J'essaie de comprendre le fonctionnement des macros va_start, va_arg et va_end, utilisées pour faire des fonctions dont le nombre de paramètres est variable.
On a:
Code:
1 2 3 4 5 6
|
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 ) |
et
Code:
typedef char * va_list;
Si je comprend l'idée:
1/ On initialise un pointeur "ap" (char* ap), vers le premier argument "inconnu" de la fonction, avec va_start.
2/ Ensuite, on parcourt les arguments en faisant "avancer le pointeur dans la pile" en bouclant va_arg
3/ quand on a fini, on fait un p'tit va_end, juste pour remettre le pointeur à NULL. C'est plus propre.
Mais il y a certaines choses que je ne comprend pas:
A. La macro _INTSIZEOF. A quoi sert-elle?
J'ai testé:
Code:
1 2 3 4 5 6 7 8 9
|
int intsizeof;
char c;
int i;
double d;
intsizeof = _INTSIZEOF(c); // <-- on obtient 4
intsizeof = _INTSIZEOF(i); // <-- on obtient 4
intsizeof = _INTSIZEOF(d); // <-- on obtient 8 |
Est-ce que c'est la taille que prend un argument passé en paramètre (posé sur la pile)?
B. Si c'est ça, je comprend bien la macro va_start(ap,v) (on fait pointer ap, derrière v, donc à "l'adresse de v + taille de v sur la pile", mais pas la macro va_arg(ap,t)?
Pour moi, ça suffirait de faire:
Code:
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) )
(on retourne un élément de type t, pointé par ap, puis on incrémente ap de la taille de cet élément.
C. Enfin, last but not least, dans les exemple que je trouve, la fonction s'attend à trouver un élément "marqueur de fin". (par exemple, la fonction fait une somme d'entier, en bouclant va_arg jusqu'à trouver un paramètre qui vaut 0, ou -1 p.ex)
Existe-t'il un moyen de faire autrement que de définir un marqueur de fin?
Merci de votre aide,
Biosox