该函数的作用就是根据结构体中一个成员变量的地址求其结构体首地址
如果要想根据结构体成员的地址求结构体的首地址,我们需要分三步:
第一步:求处成员变量的地址;
第二步:计算成员变量在该结构体中的偏移;
第三步:用第一步求出的成员变量地址减去偏移值,既得出结构体的首地址
首先我们先看下该宏的原型:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
根据上面我们列出的三步,我们分开来看:
const typeof( ((type *)0)->member ) *__mptr = (ptr);
:对应第一步,获取成员变量的地址
typeof是标准C库中的函数,函数作用是返回参数的数据类型,此处即返回成员变量member的类型。
临时变量__mptr承载ptr指针,即是成员变量的地址值
offsetof(type,member)
:对应第二步,获取成员变量在结构体中的偏移
offsetof也是标准C库中的函数,函数作用就是求出member成员在type类型结构体中的偏移(具体可参考offsetof的实现)。
(type *)( (char *)__mptr - offsetof(type,member) );
即对应第三步,将成员变量的地址减去偏移,即可得到type类型结构体的首地址
不得不说,该宏非常巧妙
原文:https://www.cnblogs.com/wangdongfang/p/13493631.html