难以理解MACRO的偏移量

Difficulty in understanding the offsetof MACRO

我一直在努力寻找(链接在最后)对 offsetof MACRO 实现的解释:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

特别是取消引用 NULL 以获得成员在结构中的偏移量。许多文章通过说 NULL 指针实际上从未真正取消引用来掩盖原因,但这对我来说没有意义。

以下是我尝试理解的一些链接:

  1. http://www.viva64.com/en/b/0301/
  2. http://www.embedded.com/design/prototyping-and-development/4024941/Learn-a-new-trick-with-the-offsetof--macro
  3. http://www.geeksforgeeks.org/the-offsetof-macro/
  4. How does the C offsetof macro work?
  5. Does dereference a NULL pointer guarantee to crash a program in C/C++?

我正在寻找并试图理解的是对编译器如何解释 MACRO 定义的逐步理解,最终将解释 NULL 指针实际上并没有被解除引用。

编辑: 尽管其他问题回答了我的问题,但它们对我来说并没有意义,正如原文 post 中指出的那样。 @dasblinkenlight 的回答阐明了我在回答其他问题时遇到的确切问题,即我们实际上并没有取消引用指针是怎么回事。

Particularly, the dereferencing of NULL to obtain the offset of the member in the structure.

没有指针的取消引用,因为运算符->的效果被运算符&:[=32=撤销了]

  • 这将是对 NULL 的取消引用:((TYPE *)0)->MEMBER
  • 在其前面加上&使其成为一个地址计算:&((TYPE *)0)->MEMBER

Many articles gloss over the reason by saying that the NULL pointer is actually never really dereferenced, but that doesn't make sense to me.

以这个例子为例:

int a;
int *p = &a;
int b = *p;     // <<== This is a dereference
int *q = &(*p); // <<== This is not a dereference

*& 这两个运算符相互取消了效果。运算符 ->*. 之上的 "syntactic sugar",因此 & 也可以撤销其效果。

当编译器看到表达式 somePointer->a 时,它获取指针的数值 somePointer,加上成员的偏移量 a,并了解您在内存中的位置可以操作。您可以对内存中的某个位置执行三项操作:

  1. 阅读
  2. 写下来
  3. 了解它的地址

第 1 项和第 2 项(读取和写入)构成取消引用。然而,第 3 项并未取消引用,因为未访问特定地址处的内存。

该宏本质上要求编译器计算成员 a 的地址,假设基地址为零。 a返回的地址自然就等于a的偏移量。您需要做的就是获取它的地址,这就是您对运算符 &.

所做的