container_of宏实现如下:

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

首先,container_of的作用是,根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针。

那么这里又涉及到 typeof 和 offsetof两个宏。

typeof 是用于得到变量的类型;typeof是GNU C对标准C的扩展。

offsetof 用于得到结构体中某个成员的内部偏移。

offsetof 的宏实现如下:

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

这里将0作为TYPE的起始地址,那么((TYPE *)0) ->MEMBER就是MEMEBER的地址,也就是偏移了。

offsetof和__builtin_offsetof实现相同。

有了typeof 和 offsetof 再来理解container_of 。第一行定义了一个 常量指针 __mptr, 指向的变量类型为member的类型, 值为ptr。

那么__mptr的地址减掉member的内部偏移就可以得到结构体的起始地址。

05-04 08:57