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
事情都是(基本的)类型检查.