这个问题并不像看起来那么明显,而且我很难bool
在标准中找到有关该类型的大量信息。
根据 C++11 标准,与bool
类型相关的保证是什么:
- 存储:它需要多少空间,忽略对齐?对将存储的值表示
true
和是否有任何要求false
? - 取值:假设
b
为 typebool
,断言是否(b == true) || (b == false)
成立?格式正确(false < true)
,是否成立?
bool
类型在第 3.9.1 节“基本类型”中进行了描述。这里相关的是第 6 段中的一句话:
type
bool
的值为true
或false
。47
参考脚注 47 提供了一些有趣的附加信息:
47 )
bool
以本国际标准描述为“未定义”的方式使用值,例如通过检查未初始化的自动对象的值,可能会导致其表现得好像既不是true
也不是false
。
这只是标准对具有未定义行为的程序没有要求的直接结果。
bool
除了由于 C++ 内存模型而适用于所有类型的隐式“至少一个字节”之外,对 没有大小要求。
对对象的内部表示也没有要求bool
,但是,由于对整数转换的要求(true
必须转换为1
和false
到0
),实现可能倾向于为true
and1
和 for false
and选择相同的表示0
,因为这样会进行这样的转换不必要。
存储:它需要多少空间,忽略对齐?
实现定义,但实际上是一个字节。它通常不能更小,因为这是可能的最小对象大小。例外情况是:
std::vector<bool>
打包值,以便每个值占用一个位;但并不真正持有 type 的对象bool
。其他类型(如std::bitset
)做类似的事情,但不要假装在 storage bool
。对将存储的值表示
true
和是否有任何要求false
?
不; 只是要求,当转换为数字类型时,true
变为 1 并false
变为 0。在实践中,这意味着实现可能会使用这些值;尽管在某些平台上,其他表示可能会更好。
取值:假设
b
为 type 的对象,bool
断言是否(b == true) || (b == false)
成立?
b
如果已初始化或分配了有效值,则断言将保持不变。如果它未初始化,那么它可能不成立;但是,如果您使用未初始化的值,无论如何您都有未定义的行为。事实上,该标准包含一个特定的脚注(由 C++11 3.9.1/6 引用)警告:
47) 以本国际标准描述为“未定义”的方式使用布尔值,例如通过检查未初始化的自动对象的值,可能会导致其表现得好像既不是真也不是假的。
更新:问题不断增长:
格式正确
(false < true)
,是否成立?
是的,是的。操作数被提升为int
,给0 < 1
,这是真的。
关于大小,如果我们从 C++ 标准草案bool
中查看5.3.3
Sizeof部分,它说(强调我的):
[...]sizeof(char)、sizeof(signed char) 和 sizeof(unsigned char) 为 1。 sizeof 应用于任何其他基本类型 (3.9.1) 的结果是实现定义的。[ 注意:特别是sizeof(bool)、sizeof(char16_t)、sizeof(char32_t) 和 sizeof(wchar_t) 是实现定义的。74 — 尾注] [...]
关于值,bool
如果我们查看3.9.1
基本类型部分,第6段说:
bool 类型的值为真或假。47
你还问:
取值:设 b 为 bool 类型的对象,断言 (b == true) || (b == false) 持有?(false < true) 格式是否正确,是否成立?
4.5
积分促销部分在第6段中说:
bool 类型的纯右值可以转换为 int 类型的纯右值,其中 false 变为 0,而 true 变为 1。
由于操作数<
被提升为int
then(false < true)
假设它b
被正确初始化(你没有调用未定义的行为)然后(b == true) || (b == false)
也成立。
有两个可能的值,true
和false
。
您可能观察到的其他任何事情都是未定义行为的结果。
在正常使用情况下,数据转换为布尔的所有非零值都被解释为真,而数据转换为布尔的所有零值都被解释为假。bool 必须至少为 1 个字节,因为 C++ 中的所有类型都必须遵守此质量。
但我在这里得到了启发,我上面的每个人都值得一票。在未定义的行为场景(例如未初始化或格式错误的数据)中,布尔值可以同时为真和假。这种奇怪的行为,但话说回来,未定义的东西总是很奇怪。谢谢大家的信息。
在评论中:此链接指向相关帖子。