0

I would like to have a conditional print macro where I can toggle it on or off based upon whether a macro is defined, such as #define DEBUG. My first thought was the following:

#define DEBUG_PRINT(...) #ifdef DEBUG printf(__VA_ARGS__) #endif

But this doesn't quite work and I get the following error when trying:

pc.c:16:24: error: '#' is not followed by a macro parameter
#define DEBUG_PRINT(...) #ifdef DEBUG printf(__VA_ARGS__) #endif

What would be a valid way to define something like a DEBUG_PRINT macro which prints if a boolean value is turned on?

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
David542
  • 104,438
  • 178
  • 489
  • 842

1 Answers1

1

The canonical way to do this is:

#ifdef DEBUG
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#endif

In case you need/want to execute multiple statements:

#define DEBUG_PRINT(...) do { printf(__VA_ARGS__); xxx; yyy; } while (0)

See also: do { ... } while (0) — what is it good for?

Finally, you probably should prefer fprintf(stderr, __VA_ARGS__) instead of just printf for debugging.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • thanks, what would be the advantage of doing the `do`... vs just `printf(__VA_ARGS__)` -- both seem to work for me and it's only a single statement, right? – David542 Mar 02 '21 at 00:07
  • 1
    @David542 hmm, yeah, I wrapped that just out of habit. If it's just a single function call you can avoid it. I'll update the answer. – Marco Bonelli Mar 02 '21 at 00:08
  • thanks, I'll accept it once it allows me to. Why do you suggest using `fprintf` for debugging? Is that so it can be sent to a logfile or something else if needed? – David542 Mar 02 '21 at 00:11
  • 1
    @David542 the main reason is that you usually should prefer debugging output going to `stderr` instead of `stdout` (which is what plain `printf` outputs to). This is because standard error is not buffered, so you see the output as soon as it's printed (even if you don't add newlines at the end), and also as you say it can be easily separated (for example piped into a log file) if needed, so you can distinguish the real output of the program from the debugging output. – Marco Bonelli Mar 02 '21 at 00:14
  • Both cases should have a `do...while(0)` or similar in order to not change the control flow depending on whether DEBUG is active or not – M.M Mar 02 '21 at 00:16
  • @M.M doesn't really alter control-flow, does it? Assuming `DEBUG` is not defined then something like `if (x) DEBUG_PRINT("a"); else yyy;` becomes `if (x); else yyy;`, which is still valid. – Marco Bonelli Mar 02 '21 at 00:21