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

2021-12-31 00:00:00 performance casting c++

扩展.

当我做这样的事情时,我觉得我很酷:

<前>bool hasParent(){返回 this->parentNode ;}

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

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

但我得到:

<前>警告 C4800:节点 *":强制将值设为布尔值真"或假"(性能警告)

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

<前>bool hasParent(){if( this->parentNode )返回真;别的返回假;}

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

解决方案

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

$ cat -n t.cpp &&cl -c -W3 -O2 -nologo -Fa t.cpp1 bool f1 (int i)2 {3 返回 i &2;4 }56 bool f2 (int i)7 {8 const bool b = i &2;9 返回 b;10 }1112 bool f3 (int i)13 {14 const bool b = 0 != (i & 2);15 返回 b;16 }t.cppt.cpp(3) : 警告 C4800: 'int' : 强制值为 bool 'true' 或 'false'(性能警告)t.cpp(8) : 警告 C4800: 'int' : 强制值为 bool 'true' 或 'false'(性能警告)

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

<块引用>

这个警告出人意料地有帮助,并且在昨天我的代码中发现了一个错误.我认为 Martin 是在断章取意地提出性能警告".

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

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

所以基本上 MS 开发人员似乎在说,如果你想将 int 'cast' 到 bool 你应该通过使用 "返回 this->parentNode != 0" 而不是隐式或显式转换.

就我个人而言,我有兴趣更多地了解警告揭示的错误类型.我认为这个警告没有多大价值.

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.

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

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?

解决方案

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:

$ 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

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

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.

相关文章