I'm working on some C code that does lot's of error reporting and logging when a DEBUG
flag is set, which sometimes produces unused variable warnings when compiling with the DEBUG
flag not set.
#ifdef DEBUG
#define CHECK(expr) foo(expr)
#else
#define CHECK(expr)
#endif /* DEBUG */
int x = bar(a, b, c); /* bar has to be called for both DEBUG begin defined and undefined */
CHECK(x == SOME_VALUE); /* Produces an "unused variable" warning if DEBUG is undefined
Edit: Just a little reminder (not sure if it is of any consequence): the argument for the CHECK
macro is an expression, not a single variable.
For this pattern, what is the best way to get rid of the unused variable warning?
What I tried/though of:
#ifdef DEBUG
int x = bar(a, b, c);
#else
bar(a, b, c);
#endif
CHECK(x == SOME_VALUE);
and then, to avoid writing the call to bar
(which is more complicated in the actual call) twice:
#ifdef DEBUG
int x =
#endif
bar(a, b, c);
CHECK(x == SOME_VALUE);
However, I feel like this is not exactly a clean and readable solution. Is there a better way? Note that for performance reasons the CHECK(expr)
macro should not produce any code if DEBUG
is undefined (EDIT: and thus, expr
should not be evaluated).
Is there a more elegant way than the one I outlined above?
#ifdef DEBUG
#define CHECK(x) x
#else
#define CHECK(x) ((void)sizeof((void)(x),0))
#endif
I think this addresses all of the possible issues :
sizeof
ensures that the expression is not evaluated at all, so its side-effects don't happen. That is to be consistent with the usual behaviour of debug-only constructs, such as assert
.((x), 0)
uses the comma operator to swallow the actual type of (x)
. This is to prevent VLAs from triggering evaluation.(void)
explicitly ignores the result of (x)
and sizeof
so no "unused value" warning appears.