Linux 内核源码
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#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);
#1. typeof # C语言库函数关键字(GNU标准),获得一个变量的类型
#2. (type*)0)->member: 把0地址转换为type结构的首地址(伪地址),然后获取该结构中member的数据类型
#3. typeof(((type *)0)->member)*__mptr = (ptr); 定义一个__mptr 指针变量,类型和member的类型一样,求出ptr的相对于0地址(伪地址)的绝对地址
#4. (type *)( (char *)__mptr - offsetof(type,member):获取该结构中member域的指针,也就是获得了member在type结构中的偏移量
# 二者相减,于是得到type类型结构体的起始地址