Rus*_*lan 29 c++ casting void compiler-warnings suppress-warnings
经常使用的语句(void)x;允许禁止有关未使用变量的警告x.但是如果我尝试编译以下内容,我会得到一些我不太了解的结果:
int main()
{
int x;
(short)x;
(void)x;
(int)x;
}
Run Code Online (Sandbox Code Playgroud)
用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;
^
Run Code Online (Sandbox Code Playgroud)
因此,我得出结论,转换为void与任何其他类型的转换非常不同,是目标类型相同decltype(x)或不同的东西.我猜测可能的解释是:
(void)x;但其他演员不会抑制警告.所有陈述同样没有任何效果.void x;并非如此short x;.哪一项更正确?如果没有,那么如何解释编译器警告的差异?
Joh*_*nck 11
这个说法:
(void)x;
Run Code Online (Sandbox Code Playgroud)
说"忽略x的价值".没有这样的类型void- 没有类型.所以它与此截然不同:
(int)x;
Run Code Online (Sandbox Code Playgroud)
其中说"将x视为整数".忽略结果整数时,会收到警告(如果已启用).
当你忽略一些什么都不是的东西时,它不被GCC认为是一个问题 - 并且有充分的理由,因为转换为void是在C和C++中显式忽略变量的惯用方法.
该标准不强制要求为未使用的局部变量或函数参数生成警告(标准语中的“诊断”)。同样,它没有强制要求如何抑制这样的警告。将变量表达式转换void为抑制此警告已成为 C 和更高版本的 C++ 社区中的习惯用法,因为结果不能以任何方式使用(除了 eg (int)x),因此不太可能只是缺少相应的代码。例如:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
Run Code Online (Sandbox Code Playgroud)
就个人而言,我觉得这个约定仍然太模糊,这就是我更喜欢使用函数模板的原因:
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
Run Code Online (Sandbox Code Playgroud)
然而,忽略函数参数的惯用方法是省略它们的名称(如上所示)。我经常使用这个函数是当我需要能够在条件编译的代码中命名一个函数参数,比如assert. 我发现例如以下比使用更清晰#ifdef NDEBUG:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
Run Code Online (Sandbox Code Playgroud)