考虑以下结构
struct a{
uint16_t foo1
uint16_t foo2
uint32_t foo3
uint64_t foo4
uint16_t foo5
uint16_t foo6
}__attribute__(packed);
它是20个字节长。很好,因为结构中的所有内容都与单词边界对齐。
但是,如果一个好心的开发人员执行以下操作,会发生什么情况
:static struct a foo;
static uint64_t b;
从理论上讲,这将使b跨字边界错位。
有趣的是,gcc似乎将foo
对齐为16个字节,但是(如果我对汇编的了解是正确的),它会使b不能对齐:
.local foo.2476
.comm foo.2476,20,16
.local b.2477
.comm b.2477,8,8
我在这里缺少什么吗?还是这是结构打包危险的一个例子?
答案 0 :(得分:2)
但是,如果一个好心的开发人员执行以下操作,会发生什么情况
:static struct a foo; static uint64_t b;
从理论上讲,这将使b跨字边界错位。
不,在这种情况下,b
不会出现未对齐的特殊原因,仅比您有
static char foo;
static uint64_t b;
。假设uint64_t
的对齐要求大于1,那么劣质的编译器可以对齐b
,但实际上,您不太可能看到这样的对齐方式结果。编译器会根据自己的判断,通常是在对齐好的地址上,对变量进行存储。
有趣的是,gcc似乎将foo对齐为16个字节,但是(如果我对汇编的了解是正确的),它允许b错位: [...]
我在这里缺少什么吗?还是这是结构打包危险的一个例子?
几乎可以肯定您缺少一些东西。我敢打赌,您的计算机uint64_t
具有4字节而不是8字节的对齐要求。