Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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++ 为什么在指向bool的强制转换指针上有性能警告?_C++_Casting_Performance - Fatal编程技术网

C++ 为什么在指向bool的强制转换指针上有性能警告?

C++ 为什么在指向bool的强制转换指针上有性能警告?,c++,casting,performance,C++,Casting,Performance,当我做这样的事情时,我觉得自己很酷: bool hasParent() { return this->parentNode ; } bool hasParent() { if( this->parentNode ) return true ; else return false ; } bool hasParent() { 返回此->父节点; } 即使投了一个(bool),警告仍然没有消失 其中,当没有父节点时,此->父节点为空 但我得到了: warnin

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

bool hasParent() { return this->parentNode ; } bool hasParent() { if( this->parentNode ) return true ; else return false ; } bool hasParent() { 返回此->父节点; } 即使投了一个(bool),警告仍然没有消失

其中,当没有父节点时,此->父节点为空

但我得到了:

warning C4800: 'Node *' : forcing value to bool 'true' or 'false' (performance warning) 警告C4800:“节点*”:强制将值设置为布尔“真”或“假”(性能警告) 怎么回事,哟?为什么这是一个性能警告?我想最好不要写这样的东西:

bool hasParent() { return this->parentNode ; } bool hasParent() { if( this->parentNode ) return true ; else return false ; } bool hasParent() { 如果(此->父节点) 返回true; 其他的 返回false; }
但是第二个版本没有生成警告,编译器似乎更高兴了。哪一个更快?

写以下内容会更有效:

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

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

return this->parentNode != 0;

bool
施放并不会使警告消失:

将表达式强制转换为bool类型不会禁用警告,这是出于设计目的

我建议采用MSDN C4800警告说明中建议的方法:

return this->parentNode != NULL;
这表明如果
parentNode
不是空指针,则返回
true
,如果
parentNode
是空指针,则返回
false

为什么这是一个性能警告

编译器正在运行以下命令:

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

这大约需要一个时钟周期比查看代码所需的时间要多。这是一个微不足道的性能差异


我认为最好写出
!=0
,因为它使代码更清晰,并使警告静音。

Microsoft Connect对此进行了讨论()。给微软的例子是:

$ 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)
微软的回应(来自负责警告的开发者)是:

这个警告非常有用,就在昨天我的代码中发现了一个bug。我认为Martin断章取义地提到了“性能警告”

这不是关于生成的代码,而是关于程序员是否表示要将值从int更改为bool。这是一种惩罚,用户可以选择一致地使用“int”而不是“bool”(反之亦然),以避免“boolifying”代码。在下面的第三种情况下,警告被抑制,因为他清楚地表示他打算接受int->bool转换

这是一个古老的警告,可能已经超出了它的目的,但它的行为就像这里设计的那样

因此,基本上MS开发人员似乎在说,如果您想将
int
强制转换为
bool
,您应该使用“
returnthis->parentNode!=0
”而不是隐式或显式强制转换来更正确地执行此操作


就我个人而言,我很想知道更多关于警告揭示了什么样的错误。我认为这个警告没有太多的价值。

编译器需要生成额外的代码来将指针转换为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
0000000000 4005e0:
布尔测试(无效*adr){
4005e0:48 85 ff测试%rdi,%rdi
4005e3:0f 95 c0设定值%al
返回adr;
}
4005f8:c3 retq


这在源代码中不直接可见,因此编译器认为这是用户应该注意的问题。

错了,编译器将生成与原始代码相同的代码。user9876,谁说它将生成更高效的代码?它省去了打字,书写部分效率更高。执行部分的效率更高。把这称为性能警告只是关于性能的愚蠢愚蠢的一部分。我的意思是与if{}else{}块相比。这也删除了警告。@Martin:我知道你这么做了。我只是对最初的编译器警告大发雷霆。对不起,我也认为这个警告是没有用的,但我还是对VC女士有偏见;-)我认为应该有一个编译器标志来启用那些无用的警告。这是“大多数C和一些C++标准库被禁止”的警告,在我使用VC的时候总是会产生一个简单的警告。0更容易出错,因为可能输入错误
返回此->parentNode=0
。bobobo:任何健全的编译器(至少是gcc)都会发出警告。如果您正确使用“const”,hasParent()将是一个const函数,因此它将是一个编译错误。如果警告是为了捕捉bug,那么它的措辞就错了。回答得好!从MS的角度来看。我想表示我不同意。。在我的if语句等中,我从不检查
if(object==NULL)
,因为可能会键入
if(object=NULL)
并以这种方式创建错误。我检查
if(object)
if(!object)
正是出于这个原因<代码>#pragma警告(disable:4800),我现在写。我更喜欢按
施放!!值
。它更短,更通用。+1使转换显式,使您的意图对下一个有权阅读代码的程序员显而易见,并承认隐式转换的性能成本。不回答问题:“为什么会有性能警告…”?一些编码标准建议在NULL==对象周围切换运算符参数,这样键入NULL=对象将导致编译器错误。哦,天哪。3000000000中的1个时钟周期?这太多了。在某些应用中,即使是一个时钟周期也很重要。实际上,这两者没有什么不同。循环计数差异仅适用于
parentNode
开始时为布尔值的情况。因为它是一个地址,它将是本机字长,你不能仅仅比较低8位就认为它是好的。如果那不是地址,是个布尔,苏尔