offsetof宏
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0) -> MEMBER)
offsetof宏作用
用于计算结构体成员在结构体中的偏移量
offsetof宏原理
TYPE : 结构体的类型
MEMBER : 结构体成员
使用结构体类型定义一个指针并指向结构体成员,表示该地址从0开始到结构体成员地址的偏移,即可计算出偏移量。
container_of宏
#define container_of(ptr, type, member) ({
const typeof( ((type *)0) -> member ) *_mptr = (ptr);
(type *)( (char *)_mptr - offsetof(type, member) );})
container_of宏作用
根据结构体某成员变量计算结构体的首地址
container_of宏原理
ptr : 结构体成员地址
type : 结构体类型
member : 结构体成员变量
const typeof( ((type *)0) -> member ) *_mptr = (ptr);该语句表示使用结构体类型的指针指向成员member,进而获取结构体成员member的类型,使用该类型定义一个指针 _mptr保存结构体的成员地址ptr。
(type *)( (char *)_mptr - offsetof(type, member) );该语句表示把 _mptr强制转换为char *类型减去member在结构体中的偏移量即可获取首地址,再把获取到的首地址强制转换为结构体类型的指针返回。
该宏为语句表达式,语句表达式的返回值为最后一条语句的结果,因此container_of宏返回的是结构体类型的指针,指向结构体的首地址。
示例
#include#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) );}) struct student { int age; int num; int math; }; int main(void) { struct student stu = {10, 20, 30}; int *ptr = &stu.num; struct student *header_add = NULL; header_add = container_of(ptr, struct student, num); printf("num offsetof in stu = %drn", offsetof(struct student, num)); printf("container_of header_add = %#prn", header_add); printf("stu header_add = %#prn", &stu); printf("header_add -> math = %drn", header_add -> math); return 0; }
上述代码运行后输出如下:
num offsetof in stu = 4 container_of header_add = 0x0061FEB8 stu header_add = 0x0061FEB8
header_add -> math = 30
可以发现使用container_of计算出来的结构体首地址和直接打印出来的结构体首地址相同,表示该宏可以获取结构体的首地址。



