Visual studio 何时布尔不是布尔(编译器警告C4800)

Visual studio 何时布尔不是布尔(编译器警告C4800),visual-studio,visual-c++,Visual Studio,Visual C++,以MS Visual Studio 2005(可能还有其他版本)中编译的内容为例: 什么。。。?MSVC编译器的大脑死了吗?据我所知,TRUE定义为1,没有任何类型信息。那么,这两条线之间有什么区别呢?在这两种情况下,括号内的表达式类型肯定是相同的吗?[问题的这一部分现在在下面的评论中得到了满意的回答] 就我个人而言,我认为通过使用==TRUE选项来避免警告是丑陋的(尽管不如!=0选项那么丑陋,尽管更严格地说是正确的),并且最好使用#pragma warning(disable:4800)来暗示

以MS Visual Studio 2005(可能还有其他版本)中编译的内容为例:

什么。。。?MSVC编译器的大脑死了吗?据我所知,TRUE定义为1,没有任何类型信息。那么,这两条线之间有什么区别呢?在这两种情况下,括号内的表达式类型肯定是相同的吗?[问题的这一部分现在在下面的评论中得到了满意的回答]

就我个人而言,我认为通过使用==TRUE选项来避免警告是丑陋的(尽管不如!=0选项那么丑陋,尽管更严格地说是正确的),并且最好使用#pragma warning(disable:4800)来暗示“我的代码很好,编译器是个混蛋”。同意吗


注意-我在C4800上看到过各种各样的讨论,讨论如何将整数分配给bool,或将带有大薯条的汉堡组合(拿着洋葱)分配给bool,并想知道为什么会有奇怪的结果。我找不到一个简单得多的问题的明确答案。。。一般来说,这可能只是C4800上的一个亮点。

实际上您不会使用断言(point1==point2)?CPoint类上的运算符显式重载,如果点相等,则返回非零;如果点不相等,则返回0。著名的ASSERT宏让我丧命,但如果您看看ASSERT宏是如何扩展的,它几乎类似于在代码中添加上面的==TRUE。看一看。请注意,示例代码明确声明不直接对两个CPoint对象使用相等运算符。我同意你的代码看起来最正确,但这就是我们喜欢C++的原因。啊…

通常,此消息是由将int变量分配给bool变量引起的

TRUE
BOOL
是整数,而不是BOOL

您还可以检查
(点1==点2)!=0或使用
!!(点1==点2)

编辑

这个!!操作只是将结果转换为bool,因为它是双负的,所以您将收到相同的结果


之前和之前都有关于这方面的讨论。

现在让我满意的答案是:

在内置类型中,运算符==返回BoL(按C++标准要求)。< /P> 对于CPoint和许多其他Microsoft类型,运算符==返回Microsoft的BOOL,即typedef'd为int

所以。。。第一个常量布尔赋值行尝试将int赋值给常量布尔,结果是C4800

第二个const bool赋值行将int与值TRUE进行比较,后者的类型定义为1(编译器假定为int),因此int==int比较的结果是bool。这将在没有警告的情况下分配给const bool

至于屏幕上最好看的东西,布拉格语既丑陋又不必要。如果您不喜欢额外的外观!=0,然后尝试以下操作:

#define ISTRUE( x )  ( (x) != 0 )

const bool point1And3Identical( ISTRUE( point1 == point2 ) );    // no warning

从语义和语法上看,这似乎是一种更好的代码整理方法。你可以悄悄地把#define for ISTRUE()塞进一个头文件,这样它看起来更漂亮。

寻找与类
CPoint
相关的
操作符==
的声明。不-你在找它:-)我在那里根本找不到任何魔力-操作符==将一个BOOL从typedef返回到int。据我所知,int==TRUE仍然是int。在内置类型上,
==
会导致
bool
,而不是
bool
。如果您确实希望运算符==返回bool,那么您也应该将Point1和Point2声明为bool以避免警告。TRUE-如果您对int或Double而不是CPoints执行相同的操作,这两种形式都没有警告。我想,==在内置类型上返回一个BoL,因为做其他事情会违反C++标准吗?这清楚地说明了发生了什么。。。但我仍然认为我更喜欢使用#pragma解决方案,或者在可能的情况下,将常量布尔赋值结构更改为if(…)。是和否。我想为常量布尔赋值的原因是为了以后在(几个)其他地方使用,在这些地方我测试if(点1和点2的名称和点3和点4的名称和点5和点5的名称…)以及类似的内容。所以ASSERT()是不合适的。而且它也会消失在发布版本中。同意断言不会出现在发布版本中。我同意在代码中禁用警告,并添加一条注释来说明为什么是这种情况下的最佳解决方案。我确实喜欢马特·米尔伍兹的建议!!(point1==point2)但我也同意这并没有真正理清语法背后的原因。祝你好运你知道的。。。我有点喜欢!!(点1==点2)作为替代。这是一件很奇怪的事情,就像布拉格语一样。任何随后试图移除的人!!将得到警告,并将面临同样的困境。但我仍然认为#布拉格马更明确地说了这一点——很有可能有人会假设!!是一个拼写错误,并将其更改为单个!,或者将==转换为a!=。创造性的回答:-)这回答了您关于C4800警告的问题,以及在您的情况下为什么会发生警告。至于你是使用宏还是!!或者!=0取消显示这些警告完全基于您的个人偏好。
#define ISTRUE( x )  ( (x) != 0 )

const bool point1And3Identical( ISTRUE( point1 == point2 ) );    // no warning