为什么offsetof宏是必要的?

7 c struct offsetof

我是C语言的新手,刚刚学习了结构和指针.

我的问题与offsetof我最近看到的宏有关.我知道它的工作原理和背后的逻辑.

在<stddef.h>文件中定义如下:

#define offsetof(type,member) ((unsigned long) &(((type*)0)->member))
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我有一个如下所示的结构:

struct test {
    int field1:
    int field2:
};

struct test var;
Run Code Online (Sandbox Code Playgroud)

为什么我不能直接获取地址field2:

char * p = (char *)&var;
char *addressofField2 = p + sizeof(int);
Run Code Online (Sandbox Code Playgroud)

而不是写这样的东西

field2Offset = offsetof (struct test, field2);
Run Code Online (Sandbox Code Playgroud)

然后将偏移值添加到var的起始地址?

有什么区别吗?使用offsetof效率更高吗?

tem*_*def 6

C 编译器通常会在 a 的成员之间添加额外的填充位或字节,struct以提高效率并保持整数字对齐(在某些体系结构中需要避免总线错误,而在某些体系结构中需要避免效率问题)。例如,在许多编译器中,如果有这样的struct:

struct ImLikelyPadded {
    int x;
    char y;
    int z;
};
Run Code Online (Sandbox Code Playgroud)

您可能会发现它sizeof(struct ImLikelyPadded)是 12,而不是 9,因为编译器将在一字节的末尾char y和字大小的int z. 这就是为什么offsetof它如此有用 - 它可以让您确定事物的真正位置,甚至可以考虑填充字节,并且具有高度可移植性。

  • 另外,该实现在宏中摆脱 UB 的唯一原因是它“就是”实现。 (2认同)