Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 向“虚空”施法的真正作用是什么?_C++_Casting_Compiler Warnings_Void_Suppress Warnings - Fatal编程技术网

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 xshort 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;
}