Question:
I have noticed this code more than once.
#if FUSE_TRACE
#define TRACE(x...) fprintf(stderr,x)
#else
#define TRACE(x...) do {} while (0)
#endif
Why so, and not
#if FUSE_TRACE
#define TRACE(x...) fprintf(stderr,x)
#else
#define TRACE(x...)
#endif
As I understand it, do {} while (0)
translated into a NOP
instruction, but why is it here?
Answer:
Macros are a subtle thing. Imagine a situation, someone wrote a code (a conditional example) (but it’s better not to write this precisely because of this).
for (int i = 0;i < 10; i++)
TRACE("ok"), s+=i;
do_any();
Everything will work correctly here. In release mode, if we use it as you suggest
#define TRACE(x...)
The following will happen, the code is converted to
if (something)
, s+=i;
do_any();
And it won't compile.
Also won't compile
expr? TRACE("y") : TRACE("n");
However, using the macro #define TRACE(x...) do {} while (0)
has similar problems. I personally use the following macro for such purposes:
#define TRACE(x...) ((void)0)
Or I use a separate function (not a macro) to display the logs.