container_of(ptr, type, member)宏根据指向结构体type中成员member的指针ptr获取该结构体的首地址,也就是获取成员member所在的结构体container。
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
* WARNING: any const qualifier of @ptr is lost.
*/
#define container_of(ptr, type, member) ({ \
void *__mptr = (void *)(ptr); \
static_assert(__same_type(*(ptr), ((type *)0)->member) || \
__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
((type *)(__mptr - offsetof(type, member))); })container_of宏实现的基本思想是从指向member的指针ptr中减去member在该结构体中的偏移量。Line 9通过typeof运算符member的实际类型,并将指向member的指针ptr转成具有该实际类型的__mptr指针。Line 10首先通过offsetof(type, member)宏获取member在结构体类型type中的偏移量。由于该偏移量表示的是字节数,因此在做指针减法运算之前,需要先将__mptr经过强制类型转换,转成char *类型。(char *)__mptr - offsetof(type,member)得到了结构体的首地址,但是是char *类型,最后还需要经过(type *)强制类型转换。