为什么这个0((类型*)0) - >成员在C?

lxg*_*eek 21 c kernel

container_of()Linux内核中的宏定义为:

#define container_of(ptr, type, member) ({ \
        const typeof( ((type*)0)->member) * __mptr =(ptr);\
        (type*)( (char*)__mptr - offsetof(type,member) );})
Run Code Online (Sandbox Code Playgroud)

为什么这样使用((type*)0)->member,不是(type*)->member吗?

cni*_*tar 20

为什么这是((类型*)0) - >成员,而不是(类型*) - >成员

仅仅因为(type*)->member语法无效,因此typeof是不可能的.所以它使用了一个NULL指针,它无论如何也不会取消引用 - 它只是用来typeof引用成员.


这是如何工作的:

  • typeof技巧用于声明成员类型的指针.使用调用者传递的指针初始化此指针获取

  • 从指针的地址中减去该成员在结构中的偏移量:这将产生包含对象的地址


Subtler问题:为什么不摆脱typeof而且只是做ptr - offsetof.char *无论如何我们正在施展它,对吧?在这种情况下,你可以传递任何东西,ptr编译器不会说任何东西.所以整个typeof事情都是(基本的)类型检查.


Som*_*ude 7

因为type*是类型而不是结构的有效实例.

指向零的指针用于获取正确的实例,但是typeof在编译时解析而不是在运行时解析指针中使用的地址不必是正确的或有效的地址.