为什么布尔值不能比作最后一点?

Why aren't bools compared by just one last bit?

本文关键字:一点 最后 布尔值 不能 为什么      更新时间:2023-10-16

最近在工作中使用 gtest 时,我收到了一些有趣的错误代码,让我想知道:

error: Expected: b1
Which is: true
To be equal to: b2
Which is: true

这是测试EXPECT_EQ(bool b1, bool b2)(伪代码(的结果。我已经做了一些挖掘,这是带有注释的示例代码:

{
bool b1, b2; //uninitialized bool variables
//lets say we are a good programmer
b1 = b2 = true;
if(b1)
if(b2)
if(b1 == b2)
std::cout << "You are a good programmer!" << std::endl;
}
{
bool b1, b2; //uninitialized bool variables
//but we are not always good programmers - b1 and b2 remains uninitialized
auto p1 = reinterpret_cast<unsigned char*>(&b1);
*p1 = 3;
auto p2 = reinterpret_cast<unsigned char*>(&b2);
*p2 = 7;
//code above is a simulation that b1 and b2 contains some trash that was left in the memory
if(b1){
std::cout << "b1 is true. n";
if(b2){
std::cout << "b2 is true. n";
if(b1 == b2)
std::cout << "b1 == b2" << std::endl;
else
std::cout << "b1 != b2" << std::endl;
}
}
}

上面的代码输出:

You are a good programmer!
b1 is true.
b2 is true. 
b1 != b2

起初,这是有道理的,你玩 UB,你得到了你应得的。我知道简单的解决方案是"做一个好的程序员并始终初始化变量",但对我来说,显示的行为使调试变得更加困难,因为如果前两个是,你会期望第三个 if 总是正确的,无论布尔变量的状态是否初始化。使用 ints 而不是 bool 运行示例代码对我来说非常有意义 - 如果C++将 0 视为false,将其他任何内容视为true,则检查if(some_int)中的整数将检查非零数字,然后比较它们将比较实际数字。

但是对于布尔值,我希望比较"函数"只检查两个状态 - 真和假,通过比较字节的最后一位,而不是所有八个在 255 个可能的状态之间进行比较。

所以我的问题是:

为什么C++比较布尔值时,比较整个字节,而不仅仅是包含真/假信息的最后一位。

最小可重复示例

一句话:效率。 比较两个字节比比较两个位所需的机器代码指令更少,因为在后一种情况下需要额外的掩码指令。

参见 Godbolt 上的示例:https://godbolt.org/z/uJ2xXy