web-dev-qa-db-fra.com

Comment faire une macro variadic (nombre variable d'arguments)

Je veux écrire une macro en C qui accepte un nombre quelconque de paramètres, pas un nombre spécifique

exemple:

#define macro( X )  something_complicated( whatever( X ) )

X est un nombre quelconque de paramètres

J'ai besoin de cela car whatever est surchargé et peut être appelé avec 2 ou 4 paramètres.

J'ai essayé de définir la macro deux fois, mais la deuxième définition a remplacé la première!

Le compilateur sur lequel je travaille est g ++ (plus précisément, mingw)

178
hasen

C99, également supporté par le compilateur C++.

#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
276
Alex B

__VA_ARGS__ est la méthode standard pour le faire. N'utilisez pas de hacks spécifiques au compilateur si vous n'en avez pas besoin.

Je suis vraiment ennuyé de ne pouvoir commenter le post original. Dans tous les cas, C++ n'est pas un sur-ensemble de C. Il est vraiment ridicule de compiler votre code C avec un compilateur C++. Ne fais pas ce que Donny ne fait pas.

33
cmccabe

Je ne pense pas que ce soit possible, vous pouvez simuler avec des doubles parens ... aussi longtemps que vous n'avez pas besoin des arguments individuellement.

#define macro(ARGS) some_complicated (whatever ARGS)
// ...
macro((a,b,c))
macro((d,e))
25
eduffy
#define DEBUG

#ifdef DEBUG
  #define PRINT print
#else
  #define PRINT(...) ((void)0) //strip out PRINT instructions from code
#endif 

void print(const char *fmt, ...) {

    va_list args;
    va_start(args, fmt);
    vsprintf(str, fmt, args);
        va_end(args);

        printf("%s\n", str);

}

int main() {
   PRINT("[%s %d, %d] Hello World", "March", 26, 2009);
   return 0;
}

Si le compilateur ne comprend pas les macros variadiques, vous pouvez également supprimer PRINT de l’un des éléments suivants:

#define PRINT //

ou

#define PRINT if(0)print

Le premier commente les instructions PRINT, le second empêche les instructions PRINT à cause d'une condition NULL si. Si l'optimisation est définie, le compilateur doit supprimer les instructions jamais exécutées telles que: if (0) print ("hello world"); ou ((vide) 0);

10
Symon

expliqué pour g ++ ici, bien que cela fasse partie de C99 alors devrait fonctionner pour tout le monde

http://www.delorie.com/gnu/docs/gcc/gcc_44.html

exemple rapide:

#define debug(format, args...) fprintf (stderr, format, args)
4
DarenW