在ANSI C中,offsetof定义如下。

#define offsetof(st, m) \
    ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))

由于我们取消引用NULL指针,为什么这不会引发分段错误?还是这种编译器黑客看到了偏移量的唯一地址,因此它静态地计算了地址而没有实际取消引用呢?此代码也可移植吗?

最佳答案

上面的代码中没有任何内容被取消引用。当在地址值上使用*->来查找引用的值时,就会发生取消引用。上面*的唯一用途是用于类型转换的类型声明。

上面使用了->运算符,但未用于访问该值。相反,它用于获取值的地址。这是一个非宏代码示例,应使其更清晰一些

SomeType *pSomeType = GetTheValue();
int* pMember = &(pSomeType->SomeIntMember);

第二行实际上并不会导致取消引用(取决于实现)。它只是返回SomeIntMember值内的pSomeType地址。

您看到的是在任意类型和char指针之间进行了大量转换。使用char的原因是,它是C89标准中唯一具有明确大小的类型之一(也许是唯一)。大小为1。通过确保大小为1,上述代码可以达到计算值的真实偏移量的魔力。

关于c - 为什么offsetof()的这种实现有效?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/713963/

10-11 17:55