为什么在offsetof()中减去空指针?

Linux的stddef.h将offsetof()定义为:

 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 

而关于offsetof() ( http://en.wikipedia.org/wiki/Offsetof )的维基百科文章将其定义为:

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

为什么在维基百科版本中减去(char *)0 ? 有什么情况会真正有所作为吗?

第一个版本将指针转换为带有强制转换的整数,这是不可移植的。

第二个版本在更广泛的编译器中更易于移植,因为它依赖于编译器的指针算法来获得整数结果而不是类型转换。

顺便说一句,我是编辑器,它将原始代码添加到Wiki条目中,这是Linux表单。 后来的编辑将其改为更便携的版本。

该标准不要求NULL指针计算为位模式0,但可以评估为特定于平台的值。

执行减法可确保在转换为整数值时,NULL为0。