简体   繁体   中英

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?

#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.

If I understood your question correctly, you can do something like

#ifdef DEBUG
.
.
#else
#define CHECK(expr) ((void)(expr))
#endif /* DEBUG */

to get rid of the warning.

With this solution there is no need for an intermediate variable.

#define DEBUG

#define DOCHECK(a) printf("DOCHECK %d\n", a)

#ifndef DEBUG
#define CHECK(a, b) a
#else
#define CHECK(a, b) do {int x = a; DOCHECK(x == b);} while (0)
#endif

int bar(int x, int y)
{
  return x+y;
}    

int main()
{
  CHECK(bar(2,3), 2+3);
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM