在 ANSI C 中,offsetof 定义如下。
#define offsetof(st, m) \
((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
既然我们解引用了一个 NULL 指针,为什么这不会引发段错误?或者这是某种编译器 hack,它看到只有偏移量的地址被取出,所以它静态计算地址而不实际取消引用它?此代码是否可移植?
最佳答案
以上代码中的任何一点都没有取消引用。当 *
或 ->
用于地址值以查找引用值时,就会发生取消引用。上面 *
的唯一用途是在用于转换目的的类型声明中。
上面使用了 ->
运算符,但它不用于访问值。相反,它用于获取值的地址。这是一个非宏代码示例,应该使它更清晰一些
SomeType *pSomeType = GetTheValue();
int* pMember = &(pSomeType->SomeIntMember);
第二行实际上并没有导致取消引用(依赖于实现)。它只是在 pSomeType
值内返回 SomeIntMember
的地址。
您看到的是任意类型和 char 指针之间的大量转换。 char 的原因是它是 C89 标准中唯一(可能是唯一)类型之一,它具有明确的大小。大小为 1。通过确保大小为 1,上面的代码可以执行计算值的真实偏移量的邪恶魔法。
关于c - 为什么这个 offsetof() 的实现有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/713963/