#include <stdarg.h> void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src);
La fonction appelée doit déclarer un objet de type va_list utilisé par les macros va_start(), va_arg() et va_end().
Le paramètre dernier est le nom du dernier paramètre avant la liste variable de paramètres, c'est-à-dire le dernier paramètre dont la fonction connaisse le type.
Comme l'adresse de ce paramètre est utilisée dans la macro va_start(), il ne doit pas être déclaré comme une variable en registre, ni comme un type fonction ou tableau.
La première utilisation de la macro va_arg() après celle de va_start() renvoie l'argument suivant dernier. Les invocations successives renvoient les valeurs des arguments restants.
S'il n'y a pas d'argument suivant, ou si type n'est pas compatible avec le type du prochain argument effectif, des erreurs imprévisibles se produiront.
Si ap est passé à une fonction qui utilise va_arg(ap,type) alors la valeur de ap est indéfinie après le retour de cette fonction.
Une implémentation évidente est de représenter va_list par un pointeur dans la pile de la fonction variadique. Dans une telle situation (de loin la plus courante), rien ne semble s'opposer à une affectation
va_list aq = ap;
Malheureusement, il y a aussi des systèmes qui créent une table de pointeurs (de longueur 1), et on devrait écrire
va_list aq; *aq = *ap;
De plus, sur les systèmes où les paramètres sont passés dans des registres, il peut être nécessaire pour va_start() d'allouer de la mémoire, d'y enregistrer les paramètres ainsi que l'indication du paramètre suivant, afin que va_arg() puisse balayer la liste. Ainsi va_end() pourra libérer la mémoire allouée. Pour gérer ces situations, C99 ajoute une macro va_copy(), afin que les affectations ci-dessus soient remplacées par
va_list aq; va_copy(aq, ap); ... va_end(aq);
À chaque invocation de va_copy() doit correspondre une invocation de va_end() dans la même fonction. Certains systèmes qui ne disposent pas de va_copy() ont une macro __va_copy() à la place, puisque c'était le nom proposé auparavant.
Interface | Attribut | Valeur |
va_start(), va_end(), va_copy() | Sécurité des threads | MT-Safe |
va_arg() | Sécurité des threads | MT-Safe race:ap |
#include <stdio.h> #include <stdarg.h>
void foo(char *fmt, ...) /* '...' is C syntax for a variadic function */
{
va_list ap;
int d;
char c;
char *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à