打包一个结构是否会错位相邻的内存?

Will packing a struct ever misalign adjacent memory?

考虑以下结构

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

我是不是遗漏了什么,或者这是结构打包的危险示例?

However, what happens if a well-meaning developer does the following:

static struct a foo;
static uint64_t b;

This would, theoretically, misalign b across a word boundary.

不,在那种情况下 b 没有特别的原因会错位,如果你

static char foo;
static uint64_t b;

。假设 uint64_t 的对齐要求大于 1,那么质量较差的编译器 可能 在这种情况下不对齐 b,但实际上,您永远不可能看到这样的结果。编译器自行决定为变量布置存储空间,通常位于对齐良好的地址。

Interestingly, gcc seems to align foo to 16 bytes, however (if my knowledge of assembly is correct), it allows b to be misaligned: [...]

Am I missing something here, or is this an example of the dangers of struct packing?

您几乎肯定遗漏了什么。我敢打赌你的机器 uint64_t 有 4 字节而不是 8 字节的对齐要求。