给定一个 POD 结构(在 C++03 中)或一个标准布局类型(在 C++11 中),所有成员都有基本对齐要求,是否可以保证每个成员都根据其对齐要求进行对齐?
换句话说,对于所有成员m_k
in { m0
... mn
标准布局类型的}S
,
struct S {
T0 m0;
T1 m1;
...
TN mn;
};
下面的表达式保证计算结果为true
?
(offsetof(S,m_k) % alignof(decltype(S::m_k))) == 0
请给出 C++03 和 C++11 的答案并引用标准的相关部分。来自 C 标准的支持证据也会有所帮助。
我对 C++03 标准 (ISO/IEC 14882:2003(E)) 的解读是,除了第一个成员之外,它对 POD 结构内成员的对齐保持沉默。相关段落是:
在规范的语言中,object是一个“存储区域”:
1.8 C++对象模型[intro.object]
1.8/1 C++ 程序中的构造创建、销毁、引用、访问和操作对象。对象是一个存储区域。 ...
对象根据其对齐要求进行分配:
3.9 类型[基本类型]
3.9/5 对象类型有对齐要求(3.9.1、3.9.2)。完整对象类型的对齐方式是一个实现定义的表示字节数的整数值;对象被分配到满足其对象类型对齐要求的地址。
基本类型有对齐要求:
3.9.1 基本类型 [basic.fundamental]
3.9.1/3 对于每个有符号整数类型,都存在一个对应的(但不同的)无符号整数类型:“unsigned char”、“unsigned Short int”、“unsigned int”和“unsigned long int”,每个类型占用相同的存储空间并与相应的有符号整数类型具有相同的对齐要求(3.9);...
Padding may由于“实现对齐要求”而发生:
9.2 类成员[class.mem]
9.2/12 声明的(非联合)类的非静态数据成员在没有介入访问说明符的情况下进行分配,以便后面的成员在类对象中具有更高的地址。非静态的分配顺序
由访问说明符分隔的数据成员未指定(11.1)。实现对齐要求可能会导致两个相邻成员不能立即分配;管理虚拟函数 (10.3) 和虚拟基类 (10.1) 的空间要求也可能如此。
9.2/12 中的“分配”一词与 3.9/5 中的“分配”含义相同吗?规范中大多数使用“分配”是指动态存储分配,而不是结构内部布局。指某东西的用途may9.2/12 中的内容似乎暗示 3.9/5 和 3.9.1/3 的对齐要求对于结构成员可能并不严格要求。
POD 结构体的第一个成员将根据结构体的对齐要求进行对齐:
9.2/17 指向 POD 结构对象的指针(使用 reinterpret_cast 进行适当转换)指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 [注意:因此,POD 结构对象内可能存在未命名的填充,但在其开头处不存在,这是实现适当对齐所必需的。 ]
[以上所有引文中都添加了强调。]