C++ 向“虚空”施法的真正作用是什么?
一种常用的语句,如C++ 向“虚空”施法的真正作用是什么?,c++,casting,compiler-warnings,void,suppress-warnings,C++,Casting,Compiler Warnings,Void,Suppress Warnings,一种常用的语句,如(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: state
(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时,code>不是有效的语句代码>是
以下哪一项更正确?如果没有,那么如何解释编译器警告的差异呢?此语句:
(void)x;
表示“忽略x的值”。没有像void
这样的类型-这是缺少类型。所以它与此非常不同:
(int)x;
当结果的整数被忽略时,你会得到一个警告(如果它被启用)
当你忽略了什么都不是的东西时,GCC不会被认为是一个问题,而且有充分的理由,因为在空的C和C++中,忽略空变量是一个习惯性的方式来忽略变量。
Cuto to Value[1]用来抑制编译器警告。§5.2.9/4中的规定如下:
任何表达式都可以显式转换为“cv void”类型
表达式值被丢弃
本标准不要求为未使用的局部变量或函数参数生成警告(“standardese中的诊断”)。同样,它也没有规定如何压制这种警告。将变量表达式转换为<代码> Value>代码>以抑制此警告已成为C和C++社区中的习惯用法,而不是因为结果不能以任何方式使用(除了例如“代码>(int)x < /COD> >),因此不太可能相应的代码丢失。例如:
(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);
可能用途:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
现在迭代器“it”指向最后一个元素我从来没有这样想过,但我有点困惑,你认为你能举个例子来澄清将变量强制转换为void
的概念吗?我很确定存在“像void
这样的类型”。请参阅[basic.types]。@Sacert:(void)x
正在将一个变量强制转换为void。你自己说的。但是,一旦您这样做了,您就不能再使用它了,因为void表达式没有任何值。将返回结果强制转换为void((void)foo()
)更有用,这表示您有意忽略返回值。我能想象将变量强制转换为无效的唯一时间是,如果该变量仅在某些#ifdef代码中使用,并且您希望在不包含该代码时抑制警告。@MartinBonner:是的,将变量强制转换为无效通常是在变量仅在assert()中使用时完成的
so将在发布版本中生成警告。这只是编译器之间的一个惯例,即此强制转换将抑制警告。C++标准没有提到“语句没有效果”的警告。因为C++ 17,你可以使用<代码> [[ MyBuunUnEu] ] < /C>属性,而不是所有这些“创造性”的方式来忽略参数。问题不是“什么时候有用”,而是“它做什么”。就像评论中提到的:“Suppress警告”
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}