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

时间:2012-12-05 12:38:01

标签: c kernel

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

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

为什么这会使用((type*)0)->member,而不是(type*)->member

2 个答案:

答案 0 :(得分:19)

  

为什么这是((type *)0) - > member,not(type *) - > member

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


这是如何运作的:

  • typeof技巧用于声明成员类型的指针。使用调用者传递的指针

  • 初始化此指针获取
  • 从结构的地址中减去结构中该成员的偏移量:这会产生包含对象的地址


Subtler问题:为什么不摆脱typeof ,只做ptr - offsetof。我们无论如何都要把它投到char *,对吧?在这种情况下,您可以传递任何内容ptr,编译器不会说任何东西。所以整个typeof事物都是(基本的)类型检查。

答案 1 :(得分:7)

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

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