GCC 中的断言和未使用的局部变量警告不能很好地混合?

Assert and unused local variable warning in GCC don't mix well?

本文关键字:很好 不能 混合 警告 局部变量 断言 未使用 GCC      更新时间:2023-10-16

我在GCC中有一个未使用的局部变量警告问题。

通常我的代码是这样的:

bool success = foo();
assert(success);

这对于调试构建很好。然而,在发布版中,assert编译为空,GCC给我一个警告。

解决这个问题的最佳方法是什么?用#ifdef包装bool success =似乎不是一个好的解决方案…

我可能会为这个场景定义一个宏

#ifndef NDEBUG
#define verify(expression) assert(expression)
#else
#define verify(expression) expression
#endif

与使用局部变量相比,我更喜欢这种方法,因为它不会用只有条件存在的值污染方法。

总的来说,我发现在我的项目中有两组宏是很有帮助的

  • assertXXX: debug only execution
  • verifyXXX:零售+调试执行

我使用了一个宏

#define UNUSED(x) ((void)(x))

像这样使用:

UNUSED(success);

宏沉默警告,并记录变量未使用(至少在某些构建中)是故意的/ok。

我不了解GCC,但这在Microsoft Visual c++中一直有效:

(void) success;

它引用变量而不做任何实际操作。

您可以使用变量属性将其标记为可能未使用。

您可以使用NDEBUG宏,它是在不使用断言时定义的,例如:

#ifndef NDEBUG
  bool success =
#endif
    foo();
  assert(success);

EDIT:这将有效地"杀死"警告,因为#ifndef将确保根本没有变量需要警告。

这是Lindydancer以定义helper宏为代价的一种更简洁的解决方案。下面是helper宏:

#ifndef NDEBUG
#  define DEBUG_ONLY( ... ) __VA_ARGS__
#else
#  define DEBUG_ONLY( ... )
#endif

那么它可以这样使用:

DEBUG_ONLY( bool success = ) foo();
assert( success );

可以使用特定于gcc的unused属性。它通常被定义为一种简短的形式,便于从非gcc编译器的代码中删除。