c - 难以理解MACRO的偏移量

标签 c pointers memory macros offsetof

我一直在努力寻找 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 指针实际上并没有被解除引用。

编辑: 尽管其他问题回答了我的问题,但正如原帖中指出的那样,它们对我来说并不有意义。 @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. 了解它的地址

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

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

关于c - 难以理解MACRO的偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36538650/

相关文章:

c - 缩小 char * 时,realloc() 的行为不符合预期

php exec 与 phing 的内存使用情况

c - 在读取内存时递增变量

c++ - 为什么我不能通过 const 指针修改变量?

c - C语言中这个typedef结构体的含义是什么?

改变指针的值

c++ - `delete <pointer>` 是只销毁指针,还是销毁指针对象?

c - 为什么递归调用函数不好?

c++ - sprintf 何时以及为何会失败?

c - 如何用数字替换文件中连续出现的字符