Les fonction à nombre d'arguments variable

Dernière mise à jour : 25/04/2009 11:30:38

Un forum web "Bien programmer en C" permet de poser des questions sur les articles, le C en général, la programmation etc.

Home

Introduction

Bien que leur usage ne soit pas recommandé, car il n'y a pas ou peu de contrôles possibles par le compilateur, le langage C supporte les fonctions à nombre variable d'arguments (variadic).

Attention ! Non seulement le nombre est variable, mais aussi le type.

Un exemple bien connu est printf().

printf ("s:%d\n", __FILE__, __LINE__);

haut


Interface

Ces prototypes sont valides :

void f(int a, ...);
int f(int a, char *b, ...);

etc.

Le rôle du dernier paramètre fixe est de fournir un moyen de déterminer le nombre et éventuellement le type des paramètres variables (donc passés après).

Exemple :

   
void f (int n, ...);

<...>
{
   f(3, 'a', 'b', 'c');
}

Ici, le dernier paramètre fixe indique le nombre de caractères passés.

Un effort particulier doit être fait au niveau de la documentation de la fonction, car il n'y a pas de contrôle possible de la part du compilateur. Si on se trompe de type ou de nombre, c'est le drame...


Implémentation

Elle varie évidemment selon la fonction à réaliser, mais elle s'appuie sur quelques principes communs :

#include <stdarg.h>

void f (int n, ...)
{
   va_list va;
   va_start (va, n);

   /* traitement des paramètres selon la fonction */

   va_end (va);
}

La récupération des paramètre se fait séquentiellement de gauche à droite par appels successifs à va_arg() en précisant le type attendu, parmi 'int', 'long', 'double', 'void*' et 'char*' [C90].

int x = va_arg (va, int);
double y = va_arg (va, double);
char *z = va_arg (va, char *);

etc.

il doit y avoir correspondance parfaite entre le type de la variable et celui passé en paramètre à la macro va_arg().

Là encore, la vigilance est de rigueur, car aucun contrôle n'est possible de la part du compilateur.

Exemple d'implémentation de la fonction présentée au-dessus.


#include <stdarg.h>
#include <stdio.h>

void f (int n, ...)
{
   va_list va;
   va_start (va, n);

   int i;

   for (i = 0; i < n; i++)
   {
      int c = va_arg (va, int);
      putchar (c);
   }
   putchar ('\n');
   va_end (va);
}

int main (void)
{
   f (3, 'a', 'b', 'c');
   f (4, 'x', 'y', 'z', 't');

   return 0;
}

abc
xyzt

Process returned 0 (0x0)   execution time : 0.025 s
Press any key to continue.

haut


Conclusion

Nous avons jeté les bases de la construction des fonctions variadics. Attention, ces fonctions sont une source importante de problèmes invisibles au yeux du compilateur.

Ne pas les utiliser dans des projets critiques sans une procédure de validation de l'implémentation et de l'usage extrêmement rigoureuse. Dans certains domaines sensibles (médical, avionique, nucléaire), leur usage est tout simplement interdit.


Valid XHTML 1.0! Valid CSS! Get Firefox!  Use OpenOffice.org Club d'entraide des développeurs francophones Code::Blocks
© Emmanuel Delahaye 2006-2009 | emmanuel dot delahaye at gmail dot com | Up | Home | Forum | Livre d'or