可能重复:
为什么这个 C 代码有效?
我确实看到定义了一个宏来计算结构偏移量,如下所示
#define offsetof(st, m) ((size_t)(&((st *)0)->m))
但我不明白这个定义是如何工作的。看起来结构的成员是通过NULL
指针访问的。谁能详细说明这个表达式是如何工作的?
可能重复:
为什么这个 C 代码有效?
我确实看到定义了一个宏来计算结构偏移量,如下所示
#define offsetof(st, m) ((size_t)(&((st *)0)->m))
但我不明白这个定义是如何工作的。看起来结构的成员是通过NULL
指针访问的。谁能详细说明这个表达式是如何工作的?
此表达式在编译时进行了优化,从而在您的程序中产生了一个编译时偏移值。
编译器看到一个常量指针(0),从它看到一个常量偏移量,然后应用常量折叠,产生地址0 + offset
(==偏移量),这就是我们需要的。
有趣的是,这是否可以在没有任何优化的情况下工作,或者总是进行一些基本的常量折叠。
PS 更准确地说,这种优化被称为Scalar Replacement of Aggregates
,正如下面雷某所指出的那样。
1) 首先创建一个指向“st”类型结构的空指针:(st *)0
2)接下来取这个结构的成员:->m
3) 接下来获取成员的地址:&(...)
4) 最后将成员的地址转换为 size-t 类型:(size_t)(...)
工作发生在第 3 步,因为指针为空(即地址 == 0),然后成员的地址仅包含结构内的成员位置。