3

I need a macro (or a function, but preferably a macro) that takes a function name and an unlimited number of arguments, then passes the arguments to the function. Let's say this macro is MACROFOO.

#define MACROFOO(function, ...)     /* what do I put here?? */

int foo_bar(int x, int y)
{
    // do stuff
}

int main(void)
{
    int x = 3;
    int y = 5;

    MACROFOO(foo_bar, x, y);    // calls foo_bar(x, y)
}

How could I define such a macro? I thought of doing something like:

#define MACROFOO(function, args...)     (function)(args)

but it looks like that passes ... to the function, instead of the actual arguments. What should I do?

MD XF
  • 7,860
  • 7
  • 40
  • 71

2 Answers2

7

You can expand the ... of variadic macros with __VA_ARGS__.

Example:

#define MACROFOO(function, ...)  (function)(__VA_ARGS__)

MACROFOO(printf, "hello world%c", '!') 
/*^ expands to: (printf)("hello world%c", '!') */

Note: As you probably know, the parentheses prevent the function argument from being expanded as a macro (if it is a macro).

I.e.,

#define BAR(...) myprintf(__VA_ARGS__)
MACROFOO(BAR, "hello world%c", '!')

will expand to:

(BAR)("hello world%c", '!')

with the parentheses and

myprintf("hello world%c", '!')

if your remove them.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
5

You can use either the standard variable argument __VA_ARGS__:

#define MACROFOO(function, ...)  (function)(__VA_ARGS__)

or if you like a more descriptive name you can use this GNU CPP extension by writing a name immediately before ... :

#define MACROFOO(function, parameters...)  (function)(parameters)

GNU CPP Section 3.6:

(...) Variadic macros are a new feature in C99. GNU CPP has supported them for a long time, but only with a named variable argument (‘args...’, not ‘...’ and __VA_ARGS__).

If you are concerned with portability to previous versions of GCC, you should use only named variable arguments. On the other hand, if you are concerned with portability to other conforming implementations of C99, you should use only __VA_ARGS__.