views:

53

answers:

2

How does the following code work?

#define ENABLE_DEBUG 1

#if ENABLE_DEBUG
    #define LOG_MSG printf
#else
    #define LOG_MSG(...)
#endif
+6  A: 

Depending on the value of ENABLE_DEBUG, LOG_MSG is either defined to be an alias for printf() or it is defined as a no-op macro. It is implied that you can change the value to 0 to disable debugging. This is a common technique for making it easy to switch between debugging builds which display lots of output and release builds which are quiet.

#define LOG_MSG printf

This makes it an alias for printf().

#define LOG_MSG(...)    /* empty */

And this defines it as an empty macro. Notice that here it has a set of parentheses, which means the macro takes parameters. It has nothing afterwards which means it expands to absolutely nothing. And the ... indicates that this macro can take a varying number of arguments. This syntax is a C99 extension so it may not be available on older C compilers.

LOG_MSG("file not found\n");

The result is that a LOG_MSG() call will either print a message or do nothing depending on whether logging is enabled.

// If ENABLE_DEBUG is non-zero, a debugging printout:
printf("file not found\n");

// If ENABLE_DEBUG is zero, an empty statement:
;

For what it's worth, whoever authored this macro could've done a better job by replacing the first definition with one using the ... syntax (which he/she is clearly familiar with), printing to stderr instead of stdout:

#define LOG_MSG(...) fprintf(stderr, __VA_ARGS__)
John Kugelman
+1  A: 

This uses the preprocessor to change code before compilation. If ENABLE_DEBUG is defined as 1, whenever the preprocessor sees

LOG_MSG("something happened");

It will replace it with

printf("something happened");

If it is defined as 0, or not defined it will replace it with nothing (as the other answer that has just been published says).

dimatura