当我做了类似的事情时,我以为自己很酷:
bool hasParent() { return this->parentNode ; }
即使使用(bool)演员,警告仍然不会消失。
如果没有父节点,则this-> parentNode为NULL。
但我得到了:
warning C4800: 'Node *' : forcing value to bool 'true' or 'false' (performance warning)
这是什么交易,哟?为什么这是表现警告?我认为不写下这样的东西会更有效率:
bool hasParent() { if( this->parentNode ) return true ; else return false ; }
但第二个版本没有产生任何警告,编译器看起来更快乐。哪个更快?
答案 0 :(得分:46)
有关此问题的讨论(What is the performance implication of converting to bool in C++?)。给微软的例子是:
$ 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)
微软的回应(来自负责警告的开发人员)是:
这个警告非常有帮助,昨天我的代码中发现了一个错误。我认为马丁正在脱离背景下的“绩效警告”。
这不是关于生成的代码,而是关于程序员是否发出了将值从int更改为bool的意图。对此有一个惩罚,并且用户可以选择一致地使用“int”而不是“bool”(或者更可能反之亦然)以避免“boolifying”codegen。警告在下面的第三种情况下被禁止,因为他明确表示他有意接受int-> bool过渡。
这是一个旧的警告,可能已经超出了它的目的,但它的行为与此处设计的一样
所以基本上MS开发人员似乎在说,如果你想要“int
向bool
投',你应该通过使用”return this->parentNode != 0
“来代替隐式或显式演员。
就个人而言,我有兴趣了解警告揭示的错误类型。我认为这个警告不会有很多价值。
答案 1 :(得分:28)
投射到bool
的事实并未使警告消失is by design:
将表达式转换为bool类型不会禁用警告,这是设计使然。
我建议使用警告C4800建议的MSDN描述的方法:
return this->parentNode != NULL;
这清楚地表明,如果true
不是空指针,则返回parentNode
;如果false
是空指针,则返回parentNode
。
答案 2 :(得分:8)
编译器需要生成用于将指针转换为bool的其他代码。它基本上是对零的比较,如果不是零则将结果设置为1。
00000000004005e0 <_Z4testPv>:
bool test(void* adr) {
4005e0: 48 85 ff test %rdi,%rdi
4005e3: 0f 95 c0 setne %al
return adr;
}
4005f8: c3 retq
这不是从源代码直接可见的,因此编译器认为这是用户应该被警告的内容。
答案 3 :(得分:7)
为什么会出现表现警告?
编译器正在转变:
bool hasParent()
{
return this->parentNode;
}
成:
bool hasParent()
{
return this->parentNode != 0;
}
这比查看代码所需的时间大约一个时钟周期。这是一个微不足道的性能差异。
我认为最好明确地写出!= 0
,因为这样可以使代码更清晰,也可以使警告静音。
答案 4 :(得分:2)
写作会更有效:
bool hasParent()
{
return this->parentNode != NULL;
}
答案 5 :(得分:1)
我很确定这是依赖于编译器的
答案 6 :(得分:0)
实际上我认为他们会优化到同样的,你也可以尝试这样做:
return this->parentNode != 0;