打包结构会不会对齐相邻的内存?

时间:2019-02-26 14:26:12

标签: c struct padding

考虑以下结构

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

我在这里缺少什么吗?还是这是结构打包危险的一个例子?

1 个答案:

答案 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字节的对齐要求。