我发现存储在 bool 变量中的值有所不同(顺便说一句,Visual-C++ 和 clang++),在存储值既不是 true 也不是 false(如果它以某种方式被破坏)的情况下,我是不确定它是 Visual-C++ 错误还是只是我应该忽略的 UB。
以下面的例子为例:
#include <cstdint>
#include <iostream>
#include <string>
#include <limits>
bool inLimits(bool const v)
{
return (static_cast<std::int32_t>(v) >= static_cast<std::int32_t>(std::numeric_limits<bool>::min()) && static_cast<std::int32_t>(v) <= static_cast<std::int32_t>(std::numeric_limits<bool>::max()));
}
int main()
{
bool b{ false };
bool const* const pb = reinterpret_cast<bool const*>(&b);
std::uint8_t * const pi = reinterpret_cast<std::uint8_t*>(&b);
std::cout << "b: " << b << " pb: " << (*pb) << " pi: " << std::to_string(*pi) << std::endl;
std::cout << "b is " << (inLimits(b) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
*pi = 3; // Simulate a bad cast during boolean creation
bool const b2{ b };
bool const b3{ *pb };
std::cout << "b: " << b << " pb: " << (*pb) << " pi: " << std::to_string(*pi) << std::endl;
std::cout << "b2: " << b2 << " b3: " << b3 << std::endl;
std::cout << "b is " << (inLimits(b) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
std::cout << "b2 is " << (inLimits(b2) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
std::cout << "b3 is " << (inLimits(b3) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
return 0;
}
这是 Visual-C++ 的输出
b: 0 pb: 0 pi: 0
b is in numeric limits for a bool
b: 3 pb: 3 pi: 3
b2: 3 b3: 3
b is not in numeric limits for a bool
b2 is not in numeric limits for a bool
b3 is not in numeric limits for a bool
这是clang++的输出
b: 0 pb: 0 pi: 0
b is in numeric limits for a bool
b: 1 pb: 1 pi: 3
b2: 1 b3: 1
b is in numeric limits for a bool
b2 is in numeric limits for a bool
b3 is in numeric limits for a bool
看起来在按值构造新 boolean 值时以及与流运算符一起使用时,clang++ 中存在限制检查。
我应该忽略它,还是只有 Visual-C++ 才有的错误? 谢谢!
编辑: 对于那些不理解示例目的的人来说,它只是一个展示,用于“模拟”内存损坏或代码另一部分中的错误,导致 boolean 值被初始化为 true 或 false 以外的东西,无论bool 的二进制表示。
(我想知道我是否必须使用断言来保护我的代码免于在其他地方不当使用,但前提是这种行为不是 UB)
第二次编辑: 添加了 numeric_limits 代码。
最佳答案
“在存储值既不是真也不是假的情况下”
为什么会这样? C++ 不限制 bool
的二进制表示。在某些编译器上,true
可以用 00000011
表示,而其他编译器可以选择将 false
表示为 00000011
。
但实际上,无论是 GCC 还是 MSVC 都没有将那个位模式用于任何一个 bool
值。这确实使它成为未定义的行为。 UB 永远不会成为编译器错误。错误是指实现无法正常工作,但 UB 具体表示任何实际行为都是可以接受的。
关于c++ - boolean 值在分配时应该被截断为 true 还是 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43371459/