更新
P1236R1: Alternative Wording for P0907R4 Signed Integers are Two's Complement 说如下:
根据圣地亚哥的 EWG 决定,与 P0907R3 不同,bool 被指定为具有某种整数类型作为其基础类型,但“bool”的填充位的存在将保持未指定,true 和 false 的映射也是如此到底层类型的值。
原答案
我相信这是未指定的,尽管false 的底层表示似乎全为零。 Boost.Container relies on this as well(强调我的):
Boost.Container 使用带有零值的 std::memset 来初始化一些
与大多数平台一样,这种初始化会产生所需的类型
具有改进性能的值初始化。
按照 C11 标准,Boost.Container 假定对于任何
整数类型,所有位都为零的对象表示
应是该类型中值零的表示。 自从
_Bool/wchar_t/char16_t/char32_t 在 C 中也是整数类型,它认为所有 C++ 整数类型都可以通过 std::memset 初始化。
他们指出的这个 C11 引用实际上来自 C99 缺陷:defect 263: all-zero bits representations 添加了以下内容:
对于任何整数类型,所有位所在的对象表示
zero 应该是该类型中值零的表示。
那么这里的问题是假设正确,C 和 C++ 之间整数的底层对象表示是否兼容?
提案Resolving the difference between C and C++ with regards to object representation of integers 试图在某种程度上回答这个问题,据我所知没有解决。我在标准草案中找不到这方面的确凿证据。我们有几个案例,它在类型方面明确链接到 C 标准。 3.9.1[basic.fundamental] 部分说:
[...] 有符号和无符号整数类型应满足
C 标准第 5.2.4.2.1 节中给出的约束。
和3.9 [basic.types] 说:
类型 T 的对象的对象表示是 N 的序列
类型 T 的对象占用的 unsigned char 对象,其中 N 等于
大小(T)。对象的值表示是一组位
保存类型 T 的值。对于普通可复制类型,值
表示是对象表示中的一组位
确定一个值,它是一个离散元素
实现定义的一组值。44
脚注 44(不规范)说:
意图是 C++ 的内存模型与 C++ 的内存模型兼容
ISO/IEC 9899 编程语言 C。
标准草案在指定 bool 的基础表示方面最远的是在3.9.1 部分:
类型 bool、char、char16_t、char32_t、wchar_t 以及带符号和
无符号整数类型统称为整数类型。 50 A
整数类型的同义词是整数类型。的表示
整数类型应使用纯二进制计数来定义值
system.51 [ 示例:本国际标准允许 2 的
补码、1 的补码和有符号幅度表示
整数类型。 ——结束示例]
该部分还说:
bool 类型的值为真或假。
但我们所知道的true 和false 是:
布尔文字是关键字 false 和 true。这样的文字
是纯右值,类型为 bool。
我们知道它们可以转换为 0 和 1:
bool 类型的纯右值可以转换为 int 类型的纯右值,用
假变零,真变一。
但这并没有让我们更接近底层表示。
据我所知,除了填充位之外,标准引用实际底层位值的唯一地方是通过defect report 1796: Is all-bits-zero for null characters a meaningful requirement? 删除的:
尚不清楚可移植程序是否可以检查表示的位;相反,它似乎仅限于检查与值表示相对应的数字位(3.9.1 [basic.fundamental] 第 1 段)。要求空字符值比较等于 0 或 '\0' 而不是指定表示的位模式可能更合适。
还有更多defect reports 处理标准中关于什么是位以及值和对象表示之间的差异的差距。
实际上,我希望这会起作用,但我认为它不安全,因为我们无法在标准中明确这一点。你是否需要改变它,不清楚,你显然有一个不平凡的权衡。所以假设它现在可以工作,问题是我们是否认为它可能会与各种编译器的未来版本中断,这是未知的。