Reputation: 381
in C, what is the proper way to define a printf like macro that will print only when DEBUG symbol is defined?
#ifdef DEBUG
#define DEBUG_PRINT(???) ???
#else
#define DEBUG_PRINT(???) ???
#endif
where ??? is where I am not sure what to fill in
Upvotes: 38
Views: 90987
Reputation: 53245
This works in both C and C++! (Note that the space before __VA_ARGS__
is required for it to work in C++!)
I see some minor errors in the implementation in the main answer. So, here is my approach:
#ifdef DEBUG
#define DEBUG_PRINTF(...) printf("DEBUG: " __VA_ARGS__)
#else
#define DEBUG_PRINTF(...) do {} while (0)
#endif
Example usage:
DEBUG_PRINTF("hello\n");
Then, if I build and run with the -DDEBUG
define on in my C build options, like this:
# Build
gcc -Wall -Wextra -Werror -std=c11 -DDEBUG -o build/my_program \
my_program_tests.c my_program.c
# Run
build/my_program
then I see this output:
DEBUG: hello
But if I build withOUT the -DDEBUG
define in my compiler C options, then I see no debug prints whatsoever.
__VA_ARGS__
. Use "DEBUG: " __VA_ARGS__
instead of "DEBUG: "__VA_ARGS__
!Upvotes: 1
Reputation: 89185
#ifdef DEBUG
#define DEBUG_PRINT(...) fprintf( stderr, __VA_ARGS__ )
#else
#define DEBUG_PRINT(...) do{ } while ( 0 )
#endif
Upvotes: 31
Reputation: 135
I like this way the best because it wont add any asm instructions to your release build.
#define DEBUG
#ifdef DEBUG
#define debug_printf(fmt, ...) printf(fmt, __VA_ARGS__);
#else
#define debug_printf(fmt, ...) /* Do nothing */
#endif
Upvotes: 0
Reputation: 775
Thank you mipadi, I improved your DEBUG_PRINT with file information too.
#define DEBUG 3
#if defined(DEBUG) && DEBUG > 0
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
__FILE__, __LINE__, __func__, ##args)
#else
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
#endif
Tested with latest clang, e.g.
int main(int argc, char **args) {
DEBUG_PRINT("Debugging is enabled.\n");
DEBUG_PRINT("Debug level: %d", (int) DEBUG);
}
outputs:
DEBUG: debug.c:13:main(): Debugging is enabled.
DEBUG: debug.c:14:main(): Debug level: 3
Upvotes: 25
Reputation: 169
Use different signatures of DEBUG_PRINT, they don't have to be the same, like:
#ifdef DEBUG
#define DEBUG_PRINT printf
#else
#define DEBUG_PRINT(...)
#endif
this way on debug mode the DEBUG_PRINT call will be replaced with printf. On release it will ignore all arguments used previously.
Hope it helps.
Upvotes: 6
Reputation: 37
You can simply use:
#ifdef DEBUG
#define DEBUG_PRINT printf
#else
#define DEBUG_PRINT
#endif
Upvotes: 2
Reputation: 5507
I've seen this idiom a fair amount:
#ifdef DEBUG
# define DEBUG_PRINT(x) printf x
#else
# define DEBUG_PRINT(x) do {} while (0)
#endif
Use it like:
DEBUG_PRINT(("var1: %d; var2: %d; str: %s\n", var1, var2, str));
The extra parentheses are necessary, because some older C compilers don't support var-args in macros.
Upvotes: 49
Reputation: 411380
Something like:
#ifdef DEBUG
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args)
#else
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
#endif
Upvotes: 22