Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to elegantly fix this unused variable warning?

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?

like image 612
mort Avatar asked May 24 '16 11:05

mort


People also ask

How do I get rid of the unused variable warning?

Solution: If variable <variable_name> or function <function_name> is not used, it can be removed. If it is only used sometimes, you can use __attribute__((unused)) . This attribute suppresses these warnings.

Why is unused variable an error?

They are warnings, if they were errors they had the bad effect of failing the compilation. Unused variable warnings are emitted during compiletime and should be a hint to you as the developer, that you might have forgotten to actually process a value that you have bound to a name. Thats the main reason for the warning.


1 Answers

#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.
like image 185
Quentin Avatar answered Sep 28 '22 10:09

Quentin