Take the 2-minute tour ×

I got stuck here...

#include <stdio.h>

#define DBG_LVL(lvl, stmt) \
do{ \
    if(lvl>1)  printf stmt; \

#define DBG_INFO(stmt)   DBG_LVL(1, stmt)
#define DBG_ERROR(stmt)  DBG_LVL(2, stmt)

int main()
    DBG_INFO(("hello, %s!\n", "world"));
    DBG_ERROR(("crazy, %s!\n", "world"));
    return 0;

As you can see, the code above uses macros like "DBG_INFO" or "DBG_ERROR" to control debug information level.

Now for some reason, I have to replace DBG_LVL() with a new function.

void myprint(int lvl, const char * format, ...);

The only difference is the debug level is taken as its fisrt parameter. I was thinking:

#define DBG_LVL(lvl, stmt) myprint(lvl, stmt)

Of course it failed, because the "stmt" expression includes parentheses around. Then I googled around trying to find a way to strip the parentheses, seems there's nothing could help. I also tried some tricks to pass parameters into "stmt", still failed... :(

Can you help me?

share|improve this question
Always google for what you want, not what you think you want. Same goes for asking people questions. –  Matt Joiner Aug 26 '11 at 23:45
Thanks. You are right. Maybe I should not put in too much subjective opinions when asking questions... –  Shello Hunter Aug 27 '11 at 0:09
add comment

2 Answers

up vote 9 down vote accepted
# define EXPAND_ARGS(...) __VA_ARGS__
# define DBG_LVL(lvl, stmt) myprint(lvl, EXPAND_ARGS stmt);
share|improve this answer
Yes! It works. This trick is awesome! actually I studied __VA_ARGS__ for a while, but i did't notice it can be used this way... even worse, i tried #define xx((stmt)) stmt, haha, compiler complained a lot..... –  Shello Hunter Aug 27 '11 at 0:02
add comment

Don't write this as a macro.

Write instead an ordinary varargs function:

void DBG_LVL(int level, char *fmt, ...)
    if (level < 1) return;

    va_list args;
    va_start(args, fmt);

    vaprintf(fmt, args);


For myprint(), define a similar vamyprint(int lvl, const char *format, va_list ap) as well, and forward the same way.

share|improve this answer
Yes, that's one way. Thanks. :) but there's some difficulties, because these macros "DBG_INFO" "DBG_ERROR" were widely used in projects, over 20 thousands files... I can't just update all these projects for this reason. –  Shello Hunter Aug 27 '11 at 0:00
add comment

Your Answer


