像(void)x;
这样经常使用的语句允许禁止有关未使用的变量x
的警告。但是如果我尝试编译以下内容,我会得到一些我不太明白的结果:
int main()
{
int x;
(short)x;
(void)x;
(int)x;
}
使用g ++编译,我收到以下警告:
$ g++ test.cpp -Wall -Wextra -o test
test.cpp: In function ‘int main()’:
test.cpp:4:13: warning: statement has no effect [-Wunused-value]
(short)x;
^
test.cpp:6:11: warning: statement has no effect [-Wunused-value]
(int)x;
^
因此,我得出结论,转换为void
与转换为任何其他类型非常不同,目标类型与decltype(x)
相同或不同。我猜测可能的解释是:
(void)x;
只是一种惯例,但其他演员不会抑制警告。所有陈述同样没有任何效果。void x;
在short x;
时不是有效陈述的事实有关。哪些更正确?如果没有,那么如何解释编译器警告的差异?
答案 0 :(得分:31)
Casting to void用于禁止编译器警告。 Standard在§5.2.9/ 4中说,
任何表达式都可以显式转换为“cv void”类型 表达式值被丢弃。
答案 1 :(得分:10)
本声明:
(void)x;
说“忽略x的值。”没有void
这样的类型 - 缺少类型。所以它与此截然不同:
(int)x;
其中说“将x视为整数”。当忽略结果整数时,会收到警告(如果已启用)。
当你忽略一些什么都不是的东西时,它不被GCC认为是一个问题 - 并且有充分的理由,因为转换为void是在C和C ++中显式忽略变量的惯用方法。
答案 2 :(得分:4)
该标准不要求对未使用的局部变量或函数参数生成警告("诊断"标准)。同样,它也没有强制要求如何抑制这种警告。将变量表达式转换为void
以抑制此警告已经成为C和后来的C ++社区中的一个习惯用语,因为结果不能以任何方式使用(例如(int)x
除外),因此它&#39 ;不太可能缺少相应的代码。 E.g:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
就个人而言,我发现这个约定仍然模糊不清,这就是为什么我更喜欢使用函数模板:
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
忽略函数参数的惯用方法是省略其名称(如上所示)。我需要经常使用此函数,因为我需要能够在有条件编译的代码中命名函数参数,例如assert
。我发现例如以下比使用#ifdef NDEBUG
更清晰:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
答案 3 :(得分:0)
可能的用途:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
现在迭代器“ it”指向最后一个元素