#define FOO(...) printf(__VA_ARGS__) #define BAR(fmt, ...) printf(fmt, __VA_ARGS__) FOO("this works fine"); BAR("this breaks!");
The use of
BAR() above is indeed incorrect according to the C99 standard, since it will expand to:
Note the trailing comma – not workable.
Some compilers (eg: Visual Studio 2010) will quietly get rid of that trailing comma for you. Other compilers (eg: GCC) support putting
## in front of
__VA_ARGS__, like so:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
But is there a standards-compliant way to get this behavior?
Perhaps using multiple macros?
Right now, the
## version seems fairly well-supported (at least on my platforms), but I'd really rather use a standards-compliant solution.
Pre-emptive: I know I could just write a small function. I'm trying to do this using macros.
Edit: Here is an example (though simple) of why I would want to use BAR():
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__) BAR("here is a log message"); BAR("here is a log message with a param: %d", 42);
This automatically adds a newline to my BAR() logging statements, assuming
fmt is always a double-quoted C-string. It does NOT print the newline as a separate printf(), which is advantageous if the logging is line-buffered and coming from multiple sources asynchronously.