Q: How can I write a macro which takes a variable number of arguments, or use the preprocessor to ``turn off'' a function call with a variable number of arguments?
A: One popular trick is to define and invoke the macro with a single, parenthesized ``argument'' which in the macro expansion becomes the entire argument list, parentheses and all, for a function such as printf:
#define DEBUG(args) (printf("DEBUG: "), printf args) if(n != 0) DEBUG(("n is %d\n", n));The obvious disadvantage is that the caller must always remember to use the extra parentheses. Another problem is that the macro expansion cannot insert any additional arguments (that is, DEBUG() couldn't expand to something like fprintf(debugfd, ...)).
gcc has an extension which allows a function-like macro to accept a variable number of arguments, but it's not standard. Other possible solutions are:
#define DEBUG(args) (printf("DEBUG: "), printf(args)) #define _ , DEBUG("i = %d" _ i);
#define DEBUG fprintf(stderr, DEBUG "%d", x);
C99 introduces formal support for function-like macros with variable-length argument lists. The notation ... can appear at the end of the macro ``prototype'' (just as it does for varargs functions), and the pseudomacro __VA_ARGS__ in the macro definition is replaced by the variable arguments during invocation.
Finally, you can always use a bona-fide function, which can take a variable number of arguments in a well-defined way. See questions 15.4 and 15.5. (If you needed a macro replacement, try using a function plus a non-function-like macro, e.g. #define printf myprintf .)
When you want to turn the debugging printouts off, you can either use a different version of your debug macro:
#define DEBUG(args) /* empty */or, if you're using real function calls, use still more preprocessor tricks to remove the function name but not the arguments, such as
#define DEBUG (void) or(These tricks are predicated on the assumption that a good optimizer will remove any ``dead'' printf calls or degenerate cast-to-void parenthesized comma expressions.) See also question 10.14.
#define DEBUG if(1) {} else printf or
#define DEBUG 1 ? 0 : (void)
Additional links: more ideas
References:
C9X Sec. 6.8.3, Sec. 6.8.3.1