linux内核细节- typeof、offsetof、container_of
来源:互联网 发布:针织毛线衣品牌知乎 编辑:程序博客网 时间:2024/05/17 02:47
container_of
链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of。
container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针,最典型的应用就是根据链表节点获取链表上的元素对象。
container_of的宏定义如下:
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
宏里面包含了两个关键字:typeof和offsetof
typeof
typeof是GNU对C新增的一个扩展关键字,用于获取一个对象的类型,在很多时候我们处理的对象通常是一个指针,而此时如果想知道指针所指向的对象的类型,typeof就派上用场了,详见GNU的官方文档 ,现在看container_of宏的第一条语句:
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
创建一个类型为const typeof( ((type )0)->member ) ,即类型为type结构的member域所对应的对象类型的常指针__mptr,并用ptr初始化之,这样一来,__mptr就指向了某一个type的member域。因为数据结构是顺序存储的,此时如果知道member在type结构中的相对偏移,那么用__mptr减去此偏移便是ptr所属的type的地址,因此宏的第二条语句应运而生:
(type *)( (char *)__mptr - offsetof(type,member) );})
offsetof
offsetof作用是返回一个数据域在它所属的数据结构中的相对偏移,单位是size_t,宏定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
将地址0强制转换为type*,那么0指向某一个type类型的对象,也就是此type对象的地址,那么(TYPE*)0)->MEMBER就是type的member域,现在取址后&((TYPE *)0)->MEMBER 就是member域的地址,因为type的地址为0,则member的地址实质上就是它相对于type地址的偏移。这里为什么可以这样实现而不会出错呢?有两点原因,其一,地址0是在编译器编译时已经指定好了的,其二,这里全部都是取址操作,并没内存数据访问,因此不会存在非法访问内存的问题。
- linux内核细节- typeof、offsetof、container_of
- offsetof typeof container_of 浅析
- container_of,offsetof,与typeof
- typeof、offsetof、container_of
- offsetof ,container_of ,typeof 用法
- typeof、offsetof、container_of的解释
- 内核:offsetof + container_of 分析
- Linux内核 container_of 宏和 offsetof 宏分析
- linux 内核中container_of和offsetof宏定义解析
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux 内核中宏 offsetof 与 container_of 的含义
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux内核 container_of 宏和 offsetof 宏分析
- 对linux内核的container_of和offsetof宏的理解
- linux kernel typeof container_of
- offsetof和container_of两个内核中的宏
- offsetof,container_of
- 经典算法题02-五家共井
- Android阅读器文字分散对齐及TextView中的字分散对齐
- Date 获取时间方法
- iOS 应用中调用系统写邮件
- mysql数据库海量数据优化方法总结
- linux内核细节- typeof、offsetof、container_of
- 做项目经常用来判断字符串的状态
- 二分法查找有序表中最接近的数值
- js中cookie的使用
- 欢迎使用CSDN-markdown编辑器
- 在Eclipse中导入jar文件
- 国产数据连接池Druid
- Js里面进行运算
- Spring 源码解析之HandlerAdapter源码解析(三)