最近,在工作中使用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一起玩,就得到了应得的。我知道一个简单的解决方案是“成为一名优秀的程序员,并始终初始化变量”,但对我来说,显示的行为使调试变得更加困难,因为如果前两个条件为真,则无论状态如何,您都希望第三个条件始终为真。布尔变量是否已初始化。用int而不是bool来运行示例代码对我来说是很有意义的-如果C ++将0false
和其他都视为true
,则检查intif(some_int)
将检查非零数字,然后进行比较将比较实际数字。
但是对于布尔,我希望通过比较字节的最后一位,比较“功能”仅检查两种状态(对与错),而不是对255种可能的状态进行比较的全部八个。
所以我的问题是:
为什么C ++在比较布尔值时会比较整个字节,而不是只包含真/假信息的最后一位。
一句话:效率。比较两个字节要比比较两个位花费更少的机器代码指令,因为在后一种情况下,需要附加的掩码指令。
参见Godbolt上的示例:https://godbolt.org/z/uJ2xXy
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句