抑制 C++ 中未使用的变量警告=>编译器错误还是代码错误?
目前,我正在使用以下函数模板来抑制未使用的变量警告:
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
}
Presently, I am using the following function template to suppress unused variable warnings:
template<typename T>
void
unused(T const &) {
/* Do nothing. */
}
However, when porting to cygwin from Linux, I am now getting compiler errors on g++ 3.4.4 (On linux I am 3.4.6, so maybe this is a bug fix?):
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
The argument to unused is a member variable declared as:
volatile bool readWriteActivated;
Is this a compiler bug or a bug in my code?
Here is the minimal test case:
template<typename T>
void unused(T const &) { }
int main() {
volatile bool x = false;
unused(!x); // type of "!x" is bool
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
指示您实际上没有使用参数的实际方法不是给它一个名称:
将在所有警告打开的情况下在任何地方进行编译,而不警告有关未使用的浮点数。即使参数在原型中确实有一个名称(例如int f(int a, float f); ),它仍然不会抱怨。
The actual way of indicating you don't actually use a parameter is not giving it a name:
will compile everywhere with all warnings turned on, without warning about the unused float. Even if the argument does have a name in the prototype (e.g.
int f(int a, float f);
), it still won't complain.我不能 100% 确定这是可移植的,但这是我通常用来抑制有关未使用变量的警告的习惯用法。这里的上下文是一个信号处理程序,仅用于捕获
SIGINT
和SIGTERM
,因此,如果该函数被调用,我知道该程序该退出了。我不太喜欢用 __attribute__((unused)) 来弄乱参数列表,因为强制转换为 void 技巧无需借助 Visual C++ 的宏即可发挥作用。
I'm not 100% sure that this is portable, but this is the idiom I've usually used for suppressing warnings about unused variables. The context here is a signal handler that is only used to catch
SIGINT
andSIGTERM
, so if the function is ever called I know it's time for the program to exit.I tend to dislike cluttering up the parameter list with
__attribute__((unused))
, since the cast-to-void trick works without resorting to macros for Visual C++.这是一个编译器错误,没有已知的解决方法:
http://gcc .gnu.org/bugzilla/show_bug.cgi?id=42655
在 v4.4 中已修复。
It is a compiler bug and there are no known work arounds:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42655
It is fixed in v4.4.
在 GCC 中,您可以按如下方式定义宏:
任何标有此宏的参数都将抑制 GCC 发出的未使用警告(并使用前缀
UNUSED_
重命名该参数)。对于 Visual Studio,您可以使用#pragma
指令抑制警告。In GCC, you can define a macro as follows:
Any parameters marked with this macro will suppress the unused warning GCC emits (and renames the parameter with a prefix of
UNUSED_
). For Visual Studio, you can suppress warnings with a#pragma
directive.haavee 提出的答案(由 ur 修改)是我通常使用的答案:
真正的问题发生在参数有时但并不总是在方法中使用时,例如:
现在,我不能注释掉参数名称 epsilon,因为这会破坏我的日志记录构建(我不想在参数列表中插入另一个 #ifdef,因为这会使代码更难阅读)。
所以我认为最好的解决方案是使用汤姆的建议:
我唯一担心的是某些编译器可能会警告“(void) epsilon;”声明,例如“声明无效”警告或类似的警告 - 我想我只需要在我可能使用的所有编译器上进行测试......
The answer proposed by haavee (amended by ur) is the one I would normally use:
The real problem happens when the argument is sometimes but not always used in the method, e.g.:
Now, I can't comment out the parameter name epsilon because that will break my logging build (I don't want to insert another #ifdef in the argument list because that makes the code much harder to read).
So I think the best solution would be to use Tom's suggestion:
My only worry would be that some compilers might warn about the "(void) epsilon;" statement, e.g. "statement has no effect" warning or some such - I guess I'll just have to test on all the compilers I'm likely to use...