【发布时间】:2018-01-08 10:33:40
【问题描述】:
这是其他question的后续行动
我试图在编译时确定特定实现是否在结构中添加了未命名的填充。像 gcc 这样的特定实现允许使用编译指示来控制结构中的填充和对齐,但代价是与其他实现兼容。由于 C11 的 n1570 草案需要 static_assert 和 offset_of,我想使用它们来查看实现是否在成员之间使用了填充。
这是代码的相关部分(参考问题中的完整代码):
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
struct quad {
int x;
int y;
int z;
int t;
};
int main() {
// ensure members are consecutive (note 1)
static_assert(offsetof(struct quad, t) == 3 * sizeof(int),
"unexpected padding in quad struct");
struct quad q;
...
正如 6.7.2.1 结构和联合说明符 § 15 所说:
在结构对象中,非位域成员和位域所在的单元 驻留的地址按照声明的顺序增加。一个指针 适当转换的结构对象指向其初始成员(或者如果该成员是 位域,然后到它所在的单元),反之亦然。可能有未命名的 在结构对象内填充,但不在其开头。
我假设如果结构中元素的偏移量是在它之前声明的元素大小的总和,那么这些元素之间不能存在填充,它们应该被连续分配,因此如果它们是同类型。
问题是:上面的假设是错误的吗(参考问题上的 cmets 让我们想想)为什么?
【问题讨论】:
-
免责声明:我知道这至少是一种极端情况,应该避免,但我真的很想了解我的假设在哪里是错误的。
标签: c struct static-assert