如何优雅地修复这个未使用的变量警告?

How to elegantly fix this unused variable warning?

我正在编写一些 C 代码,当设置了 DEBUG 标志时会执行大量错误报告和日志记录,有时会在编译时产生 未使用的变量 警告未设置 DEBUG 标志。

#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

编辑:一点提醒(不确定是否有任何影响):CHECK 宏的参数是一个 表达式,而不是单个变量 .

对于这种模式,消除未使用变量警告的最佳方法是什么?

我 tried/though 的:

#ifdef DEBUG
int x = bar(a, b, c);
#else
bar(a, b, c);
#endif
CHECK(x == SOME_VALUE);

然后,为了避免将对 bar 的调用(在实际调用中更复杂)写入两次:

#ifdef DEBUG
int x = 
#endif
bar(a, b, c);
CHECK(x == SOME_VALUE);

但是,我觉得这不是一个干净易读的解决方案。有没有更好的办法?请注意,出于性能原因,如果 DEBUG 未定义,CHECK(expr) 宏不应生成任何代码(EDIT:,因此不应评估 expr ).

有没有比我上面概述的更优雅的方式?

如果我没有正确理解你的问题,你可以这样做

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

消除警告。

有了这个解决方案就不需要中间变量了。

#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;
}
#ifdef DEBUG
    #define CHECK(x) x
#else
    #define CHECK(x) ((void)sizeof((void)(x),0))
#endif

我认为这解决了所有可能的问题:

  • sizeof 确保表达式根本不被计算,所以它的副作用不会发生。这是为了与仅调试构造的通常行为一致,例如 assert.
  • ((x), 0) 使用逗号运算符吞没 (x) 的实际类型。 .
  • (void) 明确忽略 (x)sizeof 的结果,因此不会出现 "unused value" 警告。