我一直在努力寻找 offsetof MACRO 实现的解释(链接在最后):
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
特别是取消引用 NULL 以获得成员在结构中的偏移量。许多文章通过说 NULL 指针实际上从未真正取消引用来掩盖原因,但这对我来说没有意义。
以下是我尝试理解的一些链接:
- http://www.viva64.com/en/b/0301/
- http://www.embedded.com/design/prototyping-and-development/4024941/Learn-a-new-trick-with-the-offsetof--macro
- http://www.geeksforgeeks.org/the-offsetof-macro/
- How does the C offsetof macro work?
- Does dereference a NULL pointer guarantee to crash a program in C/C++?
我正在寻找并试图理解的是对编译器如何解释 MACRO 定义的逐步理解,最终将解释 NULL 指针实际上并没有被解除引用。
编辑: 尽管其他问题回答了我的问题,但正如原帖中指出的那样,它们对我来说并不有意义。 @dasblinkenlight 的回答阐明了我在回答其他问题时遇到的确切问题,即我们实际上没有取消引用指针是怎么回事。
最佳答案
Particularly, the dereferencing of NULL to obtain the offset of the member in the structure.
没有指针的解引用,因为运算符 ->
的效果被运算符 &
撤消了:
- 这将是对
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
*
和&
这两个运算符相互取消了效果。运算符 ->
是 *
和 .
之上的“语法糖”,因此 &
可以撤销其效果
当编译器看到表达式 somePointer->a
时,它获取指针 somePointer
的数值,加上成员 a
的偏移量,并了解您可以在内存中进行操作的位置。您可以对内存中的某个位置执行三项操作:
- 阅读
- 写下来
- 了解它的地址
第 1 项和第 2 项(读和写)构成解引用。然而,第 3 项并未解除引用,因为未访问特定地址处的内存。
宏本质上要求编译器计算成员 a
的地址,假设基地址为零。返回的a
的地址自然等于a
的偏移量。您需要做的就是获取它的地址,这就是您使用运算符 &
所做的。
关于c - 难以理解MACRO的偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36538650/