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宏的总结的主要内容,如果未能解决你的问题,请参考以下文章