用 u_long 填充 C 结构

Padding in a C struct with u_long

所以我在 C 中定义了一个结构:

struct example {
  int ex1;
  u_long ex2;
  float ex3;
  float ex4;
};

所以示例的所有成员的大小都是 20,但是示例的大小是 24,这意味着正在添加填充。我真正不明白的是为什么以及在哪里。

对不起,如果我的术语不正确,但我认为因为它是 4 字节干净的(即所有成员的大小 % 4 == 0 ),所以不需要添加填充。是因为我是 运行 x86 它需要 8 字节干净,还是这只是常态?

然后我真的不知道填充在哪里添加,我会假设在 u_long 附近,但我不确定。

结构通常也会在末尾进行填充,以便结构的总大小可以被具有最大对齐的成员所需的对齐整除。

在您的例子中,u_long 需要对齐 8 个字节,并且将它放在第一个成员末尾后 4 个字节处,因此它的地址位于 8 个字节的边界上。结构的总大小变为 24,因此它不需要在末尾进行任何额外的填充。

末尾填充可确保在顺序数组中布局时,第二个元素不会破坏某些成员的对齐方式。

这是一个测试,运行 在一台特定的机器上,您的结果可能会有所不同:

$ cat ul.c
#include <stdio.h>

struct example {
  int ex1;
  unsigned long ex2;
  float ex3;
  float ex4;
};

struct example ex;

int main ( void ) {
        printf("Size:\t%zd\n", sizeof(ex));
        printf("ex @\t%p\n", &ex);
        printf("ex1 @\t%p\n", &ex.ex1);
        printf("ex2 @\t%p\n", &ex.ex2);
        printf("ex3 @\t%p\n", &ex.ex3);
        printf("ex4 @\t%p\n", &ex.ex4);
        return 0;
}

$ ./ul
Size:   24
ex @    0x600940
ex1 @   0x600940
ex2 @   0x600948
ex3 @   0x600950
ex4 @   0x600954

此处填充在ex1和ex2之间。

I thought that since it was 4 byte clean (i.e. size of all members % 4 == 0 ) that padding wouldn't need to be added.

这不是一个安全的假设。 C 对可以向 struct 表示中添加多少填充或在何处添加几乎没有限制。它根本没有说明什么时候或为什么。这些选择取决于编译器。

Is it because I am running an x86 that it needs to be 8 byte clean, or is that just the norm?

您假设“8 字节干净”与填充有任何关系。它可能会,但同样,这是一个实施决定。

一般来说,编译器会插入填充以确保所有成员都可以对齐,以便在 struct 数组的每个元素中实现最佳访问。这可能需要在成员之间或末尾或两者之间进行填充。但这仍然是一个实施考虑因素。如果你想知道你正在使用的特定 C 实现如何解决这个问题,那么你需要查阅它的文档。