在K&R C编程代码中,给出如下代码

typedef long Align;     /* for alignment to long boundary */

union header {          /* block header: */
    struct {
        union header *ptr;     /* next block if on free list */
        unsigned size;         /* size of this block */
    } s;
    Align x;            /* force alignment of blocks */
};

typedef union header Header;

然后它继续说“从未使用过 Align 字段;它只是强制每个 header 在一个
最坏情况边界”。我已经多次阅读文本,但仍然不明白为什么需要 long 对齐。SIZE 是一个 int 并且 PTR 是 4 个字节,所以它不应该对齐吗?为什么使用 long,和不是int?谢谢。

最佳答案

那是一本很旧的书。当时很多机器上的指针只有 16 位,而 long 是 32 位,所以 union 强制对齐到 32 位。

正如@Deduplicator 指出的那样,仍然有许多嵌入式系统使用 16 位指针。

针对评论进行编辑:对齐的主题相当广泛且充满细微差别。为了简单起见,接下来的讨论做出了这些假设

  • 指针是 16 位
  • int 是 16 位
  • long 是 32 位
  • 处理器有严格的对齐要求,即 16 位值只能在 2 字节边界上访问,32 位值只能在 4 字节边界上访问。

  • 以下结构将占用 32 位
    struct header {
        struct header *ptr;
        unsigned size;
    };
    

    但是,结构中的字段每个仍然是 16 位。因此,对齐要求仍然只有 16 位。因此,例如,将结构放置在地址 0xAA02 将是完全有效的,因为 ptr 将位于对齐地址 (0xAA02) 并且 size 也将位于对齐地址 (0xAA04)。

    然而,地址 0xAA02 对于 union 并不合适,因为 union 的 x 字段需要 32 位对齐。因此,将结构置于与 x 的 union 中会强制编译器将结构置于 4 字节边界上,否则它可以置于 2 字节边界上。

    关于 union 中的 C 对齐,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28245162/

    10-16 21:24