container_of宏和offsetof宏的总结

Posted reviewing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了container_of宏和offsetof宏的总结相关的知识,希望对你有一定的参考价值。

1、offsetof 宏

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

将地址0强制转换为type类型的指针,从而得到结构体成员member相对于结构体起始地址的偏移量。

 

2、container_of 宏 

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

作用:结构体(type)的成员member地址 减去 member在type中的偏移 得到该结构体(type)的起始地址。

container_of 宏分为两部分:

 第一部分:const typeof( ((type *)0)->member ) *__mptr = (ptr);
   通过typeof定义一个member指针类型的指针变量__mptr,并将__mptr赋值为ptr。
 第二部分:(type *)( (char *)__mptr - offsetof(type,member) );
   通过offsetof宏计算出member在type中的偏移,
   然后用member的实际地址__mptr减去偏移,得到type的起始地址,即指向type类型的指针。

 

测试代码:

 1 #include <stdio.h>
 2 
 3 #define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)
 4 
 5 #define container_of(ptr, type, member) ({   6     const typeof( ((type *)0)->member) *__mptr = (ptr);   7     (type *)( (char *)__mptr - offsetof(type, member));})
 8 
 9 typedef struct{
10     int id;
11     char name[20];
12     int age;
13 }student;
14 
15 int main()
16 {
17     printf("%lu
", offsetof(student, id));
18     printf("%lu
", offsetof(student, name));
19     printf("%lu
", offsetof(student, age));
20 
21     student s;
22     s.age = 20;
23     student *ps = container_of(&s.age, student, age);
24     printf("%d
", ps->age);
25     printf("%p
", &s);
26     printf("%p
", ps);
27     
28     return 0;
29 }

运行结果:

技术分享图片

 





以上是关于container_of宏和offsetof宏的总结的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式开发知识点总结

offsetof宏与container_of宏

typeof, offsetof 和container_of

offsetof与container_of宏分析

container_of 和 offsetof宏

linux内核中的offsetof与container_of宏