C++ 为什么将指针转换为 bool 时会出现性能警告?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1847860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:23:18  来源:igfitidea点击:

Why is there a performance warning on cast pointer to bool?

c++castingperformance

提问by bobobobo

Extends.

延伸

I thought I was being cool when I did something like:

当我做这样的事情时,我认为我很酷:

bool hasParent()
{
  return this->parentNode ;
}

Even with a (bool) cast, the warning still doesn't go away.

即使使用 (bool) 强制转换,警告仍然不会消失。

Where this->parentNode is NULL when there is no parent node.

当没有父节点时,this->parentNode 为 NULL。

But I'm getting:

但我得到:

warning C4800: 'Node *' : forcing value to bool 'true' or 'false' (performance warning)

What's the deal, yo? Why is that a performance warning? I thought it'd be more efficient to not write something like:

怎么了,哟?为什么这是一个性能警告?我认为不写这样的东西会更有效率:

bool hasParent()
{
  if( this->parentNode )
    return true ;
  else
    return false ;
}

But the second version generates no warnings and the compiler seems a lot happier. Which is faster though?

但是第二个版本没有产生警告,编译器似乎更快乐。哪个更快?

采纳答案by Michael Burr

There's a discussion on Microsoft Connect about this (What is the performance implication of converting to bool in C++?). The example given to Microsoft is:

在 Microsoft Connect 上有一个关于此的讨论(在 C++ 中转换为 bool 的性能影响是什么?)。给微软的例子是:

$ cat -n t.cpp && cl -c -W3 -O2 -nologo -Fa t.cpp
1 bool f1 (int i)
2 {
3 return i & 2;
4 }
5
6 bool f2 (int i)
7 {
8 const bool b = i & 2;
9 return b;
10 }
11
12 bool f3 (int i)
13 {
14 const bool b = 0 != (i & 2);
15 return b;
16 }
t.cpp
t.cpp(3) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
t.cpp(8) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

And Microsoft's response (from the developer responsible for the warning) is:

而微软的回应(来自负责警告的开发者)是:

This warning is surprisingly helpful, and found a bug in my code just yesterday. I think Martin is taking "performance warning" out of context.

It's not about the generated code, it's about whether or not the programmer has signalled an intent to change a value from int to bool. There is a penalty for that, and the user has the choice to use "int" instead of "bool" consistently (or more likely vice versa) to avoid the "boolifying" codegen. The warning is suppressed in the third case below because he's clearly signalled his intent to accept the int->bool transition.

It is an old warning, and may have outlived its purpose, but it's behaving as designed here

这个警告非常有用,昨天在我的代码中发现了一个错误。我认为 Martin 是在断章取意地提出“性能警告”。

这与生成的代码无关,而与程序员是否已发出将值从 int 更改为 bool 的意图有关。对此有一个惩罚,用户可以选择一致地使用“int”而不是“bool”(或者更有可能反之亦然)以避免“boolifying”代码生成。在下面的第三种情况下,警告被抑制了,因为他明确表示他打算接受 int->bool 转换。

这是一个旧警告,可能已经超出其目的,但它的行为与此处设计的一样

So basically the MS developer seems to be saying that if you want to 'cast' an intto boolyou should more properly do it by using "return this->parentNode != 0" instead of an implicit or explicit cast.

因此,基本上 MS 开发人员似乎在说,如果您想将一个“转换”intbool您,则应该使用“ return this->parentNode != 0”而不是隐式或显式转换来更正确地执行此操作。

Personally, I'd be interested to know more about what kind of bugs the warning uncovers. I'd think that this warning wouldn't have a whole lot of value.

就我个人而言,我有兴趣了解更多有关警告揭示的错误类型的信息。我认为这个警告不会有很大的价值。

回答by James McNellis

The fact that casting to booldoes not make the warning go away is by design:

投射到bool不会使警告消失的事实是设计使然

Casting the expression to type bool will not disable the warning, which is by design.

将表达式转换为 bool 类型不会禁用警告,这是设计使然。

I would recommend the approach that the MSDN description of warning C4800 recommends:

我会推荐警告 C4800 的 MSDN 描述推荐的方法:

return this->parentNode != NULL;

this makes it clear that you are returning trueif parentNodeis not a null pointer and falseif parentNodeis a null pointer.

这清楚地表明您正在返回trueifparentNode不是空指针并且falseifparentNode是空指针。

回答by Gunther Piez

The compiler needs to generate additional code for converting a pointer to bool. It is basically a comparision against zero and setting the result to one if not zero.

编译器需要生成额外的代码来将指针转换为 bool。它基本上是与零的比较,如果不是零,则将结果设置为一。

00000000004005e0 <_Z4testPv>:
bool test(void* adr) {
  4005e0:       48 85 ff                test   %rdi,%rdi
  4005e3:       0f 95 c0                setne  %al
    return adr;
}
  4005f8:       c3                      retq

This isn't directly visible from the source, so the compiler thinks this is something the user should be warned about.

这不是从源代码直接可见的,所以编译器认为这是用户应该被警告的事情。

回答by user9876

Why is that a performance warning?

为什么这是一个性能警告?

The compiler is turning this:

编译器正在转向:

bool hasParent()
{
  return this->parentNode;
}

into:

进入:

bool hasParent()
{
  return this->parentNode != 0;
}

This takes about one clock cyclemore than you might expect from looking at the code. It's an insignificant performance difference.

这比您在查看代码时预期的要多花费大约一个时钟周期。这是一个微不足道的性能差异。

I think it's better to write out the != 0explicitly anyway, as it makes the code clearer as well as silencing the warning.

我认为最好!= 0还是明确写出,因为它使代码更清晰并消除警告。

回答by Martin York

It would be more efficient to write:

写成这样会更有效率:

bool hasParent()
{
    return  this->parentNode != NULL;
}

回答by user224003

I'm pretty sure this is compiler dependent

我很确定这取决于编译器

回答by UberJumper

Realistically i think they would optimize to the same, you can also try doing this:

实际上,我认为他们会优化为相同的,您也可以尝试这样做:

return this->parentNode != 0;