typeof、offsetof、container_of
来源:互联网 发布:淘宝旗舰店和京东自营 编辑:程序博客网 时间:2024/06/08 19:19
链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of。创建一个类型为const typeof( ((type *)0)->member ) *,即类型为type结构的member域所对应的对象类型的常指针__mptr,并用ptr初始化之,这样一来,__mptr就指向了某一个type的member域。因为数据结构是顺序存储的,此时如果知道member在type结构中的相对偏移,那么用__mptr减去此偏移便是ptr所属的type的地址,因此宏的第二条语句应运而生:另一个主角出场了---offsetof,返回一个数据域在它所属的数据结构中的相对偏移,单位是size_t,宏定义如下:将地址0强制转换为type *,那么0指向某一个type类型的对象,也就是此type对象的地址,那么(TYPE *)0)->MEMBER就是type的member域,现在取址后&((TYPE *)0)->MEMBER 就是member域的地址,因为type的地址为0,则member的地址实质上就是它相对于type地址的偏移。这里为什么可以这样实现而不会出错呢?有两点原因,其一,地址0是在编译器编译时已经指定好了的,其二,这里全部都是取址操作,并没内存数据访问,因此不会存在非法访问内存的问题。
container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针,最典型的应用就是根据链表节点获取链表上的元素对象。
这个宏乍一看有点瘆人,宏里面包含了两个关键字:typeof和offsetof:
container_of的宏定义如下:
- #define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
typeof是GNU对C新增的一个扩展关键字,用于获取一个对象的类型,在很多时候我们处理的对象通常是一个指针,而此时如果想知道指针所指向的对象的类型,typeof就派上用场了,详见GNU的官方文档:http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
现在看container_of宏的第一条语句:
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
- #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
这样贯穿起来看,其实container_of的实现其实也是蛮清晰的,记得某位兄台说过一句话:一切事物在你看清楚它的本质之前,对你而言总是朦胧的。
0 0
- offsetof typeof container_of 浅析
- container_of,offsetof,与typeof
- typeof、offsetof、container_of
- offsetof ,container_of ,typeof 用法
- typeof、offsetof、container_of的解释
- linux内核细节- typeof、offsetof、container_of
- offsetof,container_of
- offsetof和container_of
- offsetof与container_of宏
- 内核:offsetof + container_of 分析
- offsetof和container_of
- offsetof、container_of 实现
- container_of与offsetof详解
- offsetof和container_of总结
- offsetof与container_of宏
- offsetof与container_of
- container_of与offsetof的原理
- container_of 和 offsetof 宏详解
- HDU 5650 so easy 水的666
- 大数相乘算法 List实现
- 蓝桥杯:字母图形
- 分页加载Demo
- ISE综合选项Keep Hierarchy
- typeof、offsetof、container_of
- 《vb.net视频之沉淀》
- Mentor.Graphics.FloTHERM.XT.2.3+Mentor.Graphics.Flowmaster.7.9.4
- 实验环境Ceph 9.2.1部署笔记
- 递归求解逆波兰表达式
- 笔记-一些MOS管和栅驱
- Java 学习笔记
- EM算法(Expectation Maximization Algorithm)
- Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法