11

目前,我正在使用以下函数模板来抑制未使用的变量警告:

template<typename T>
void
unused(T const &) {
  /* Do nothing. */
}

但是,当从 Linux 移植到 cygwin 时,我现在在 g++ 3.4.4 上遇到编译器错误(在 linux 上我是 3.4.6,所以也许这是一个错误修复?):

Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1

未使用的参数是一个成员变量,声明为:

  volatile bool readWriteActivated;

这是编译器错误还是我的代码中的错误?

这是最小的测试用例:

template<typename T>
void unused(T const &) { }

int main() {
  volatile bool x = false;
  unused(!x); // type of "!x" is bool
}
4

5 回答 5

28

指示您实际上不使用参数的实际方法是不给它一个名称:

int f(int a, float) {
     return a*2;
}

将在所有警告打开的情况下在任何地方编译,而不会警告未使用的浮点数。即使参数在原型中确实有一个名称(例如int f(int a, float f);),它仍然不会抱怨。

于 2009-12-15T09:25:06.740 回答
9

我不是 100% 确定这是可移植的,但这是我通常用来抑制未使用变量的警告的惯用语。这里的上下文是一个仅用于捕获SIGINTand的信号处理程序SIGTERM,因此如果曾经调用过该函数,我知道该程序退出了。

volatile bool app_killed = false;
int signal_handler(int signum)
{
    (void)signum; // this suppresses the warnings
    app_killed = true;
}

我倾向于不喜欢用 来弄乱参数列表__attribute__((unused)),因为 cast-to-void 技巧可以在不借助 Visual C++ 的宏的情况下工作。

于 2009-12-15T05:35:02.850 回答
4

这是一个编译器错误,没有已知的解决方法:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42655

它已在 v4.4 中修复。

于 2009-12-16T01:51:59.510 回答
2

在 GCC 中,您可以如下定义宏:

#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif 

任何标有此宏的参数都将抑制 GCC 发出的未使用警告(并使用前缀重命名参数UNUSED_)。对于 Visual Studio,您可以使用#pragma指令抑制警告。

于 2009-12-15T04:56:35.540 回答
2

haavee 提出的答案(由 ur 修改)是我通常使用的答案:

int f(int a, float /*epsilon*/) {
     return a*2;
}

真正的问题发生在有时但并不总是在方法中使用参数时,例如:

int f(int a, float epsilon) {
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

现在,我不能注释掉参数名称 epsilon,因为这会破坏我的日志构建(我不想在参数列表中插入另一个 #ifdef,因为这会使代码更难阅读)。

所以我认为最好的解决方案是使用汤姆的建议:

int f(int a, float epsilon) {
(void) epsilon;    // suppress compiler warning for possibly unused arg
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

我唯一担心的是一些编译器可能会警告“(void) epsilon;”。声明,例如“声明无效”警告或类似的 - 我想我只需要测试我可能使用的所有编译器......

于 2010-10-06T16:58:39.647 回答