views:

5285

answers:

4

I want to write a macro in C that accepts any number of parameters, not a specific number

e.g.

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

where X is any number of parameters

I need this because whatever is overloaded and can be called with 2 or 4 parameters.

I tried defining the macro twice, but the second definition overwrote the first one!

The compiler I'm working with is g++ (more specifically, mingw)

+1  A: 

explained for g++ here, though it is part of C99 so should work for everyone

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

quick example:

#define debug(format, args...) fprintf (stderr, format, args)
DarenW
GCC's variadic macros are not C99 variadic macros. GCC _has_ C99 variadic macros, but G++ doesn't support them, because C99 is not part of C++.
Chris Lutz
Actually g++ will compile C99 macros in C++ files. It will issue a warning, however, if compiled with '-pedantic'.
Alex B
It is not C99. C99 use __VA_ARGS__ macro).
qrdl
Wrong, __VA_ARGS__ is standard.
Justicle
+2  A: 

I don't think that's possible, you could fake it with double parens ... just as long you don't need the arguments individually.

#define macro(ARGS) some_complicated (whatever ARGS)
// ...
macro((a,b,c))
macro((d,e))
eduffy
C99 adds variadic macros.
Chris Lutz
While it is possible to have a variadic macro, using double parenthesis is a good advice.
David Rodríguez - dribeas
+13  A: 

C99 way, also supported by VC++ compiler.

#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
Alex B
I don't think C99 requires the ## before __VA_ARGS__. That might just be VC++.
Chris Lutz
You are right. I remember having decided to put it in my vararg macros in distant past, but couldn't remember the exact reason.
Alex B
The reason for ## before __VA_ARGS__ is that it swallows the preceding comma in case the variable-argument list is empty, eg. FOO("a") expands to printf("a"). This is an extension of gcc (and vc++, maybe), C99 requires at least one argument to be present in place of the ellipsis.
jpalecek
A: 
#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;
}

If the compiler does not understand variadic macros, you can also strip out PRINT with either of the following:

#define PRINT //

or

#define PRINT if(0)print

The first comments out the PRINT instructions, the second prevents PRINT instruction because of a NULL if condition. If optimization is set, the compiler should strip out never executed instructions like: if(0) print("hello world"); or ((void)0);

#define PRINT // will not replace PRINT with //
bitc
#define PRINT if(0)print is not a good idea either because the calling code might have its own else-if for calling PRINT. Better is: #define PRINT if(true);else print
bitc