2010-03-22

#1 C Macro Pet Peeve: use do while 0

I cannot fathom why I still see compound macros like:
#define TRACE(fmt, ...) { \
printf(fmt, ##__VA_ARGS__); fflush(stdout); \
}

Please, use do while 0:
#define TRACE(fmt, ...) do { \
printf(fmt, ##__VA_ARGS__); fflush(stdout); \
} while (0)

Don't worry. Your (any remotely recent) compiler will not generate any assembly code for the "do while 0". For an explanation, just search do while 0. The basic idea is that you want these kind of macros to behave like normal C void methods. However, if you use the original macro in an expression such as "if (expr) TRACE("yes"); else TRACE("no");", the semicolons after the expansion will cause syntax errors.

For more options to use instead of do while 0, see G_STMT_START/END macros in glib.h, depending on what your compiler allows:
#define TRACE(fmt, ...) if(0) { \
printf(fmt, ##__VA_ARGS__); fflush(stdout); \
} else (void)0

#define TRACE(fmt, ...) (void) ({ \
printf(fmt, ##__VA_ARGS__); fflush(stdout); \
})

1 comment:

  1. So, my only real question here is.... Do others tease you about the institute thing, too? LOL...

    ReplyDelete