内核链表中list_entry()函数
2014-03-22 21:40
288 查看
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
所以在这分析一下container_of宏和其中的offsetof宏
1、#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )
宏功能:获得一个结构体变量成员在此结构体中的偏移量。
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址,即相对于0的偏移量,要的就这个;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型,size_t应该最终为unsigned int类型。
此宏的巧妙之处在于将 0 转换成(TYPE*),这样结构体中成员的地址即为在此结构体中的偏移量。
2、#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
宏功能:从结构体(type)某成员变量(member)指针(ptr)来求出该结构体(type)的首指针。
1、typeof( ( (type *)0)->member )为取出member成员的变量类型。
2、定义__mptr指针ptr为指向该成员变量的指针
3、mptr为member数据类型的常量指针,其指向ptr所指向的变量处
4、(char *)__mptr转换为字节型指针。(char *)__mptr - offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr -offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
5、({ })这个扩展返回程序块中最后一个表达式的值。
转至:http://zhouyang340.blog.163.com/blog/static/30240959201296102832114/
container_of(ptr, type, member)
所以在这分析一下container_of宏和其中的offsetof宏
1、#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )
宏功能:获得一个结构体变量成员在此结构体中的偏移量。
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址,即相对于0的偏移量,要的就这个;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型,size_t应该最终为unsigned int类型。
此宏的巧妙之处在于将 0 转换成(TYPE*),这样结构体中成员的地址即为在此结构体中的偏移量。
2、#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
宏功能:从结构体(type)某成员变量(member)指针(ptr)来求出该结构体(type)的首指针。
1、typeof( ( (type *)0)->member )为取出member成员的变量类型。
2、定义__mptr指针ptr为指向该成员变量的指针
3、mptr为member数据类型的常量指针,其指向ptr所指向的变量处
4、(char *)__mptr转换为字节型指针。(char *)__mptr - offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr -offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
5、({ })这个扩展返回程序块中最后一个表达式的值。
转至:http://zhouyang340.blog.163.com/blog/static/30240959201296102832114/
相关文章推荐
- 生命周期
- Qt开发环境搭建(Linux)
- jsp数据库连接大全和数据库操作封装到Javabean
- ios中的键盘处理和UIApplication AppDelete等小知识补充
- 利用HTML5,前端js实现图片压缩
- Knuth-Morris-Pratt Algorithm
- 在stm32上移植wpa_supplicant(二)
- cacti被控端配置脚本
- COM学习笔记(一)
- 构建一个高可扩展性javabean和jsp连接数据库操作
- [Excel]C#操作Excel(导入导出)
- Design Pattern - Java 设计模式实战精髓
- warning: incompatible implicit declaration of built-in function
- ACMer必备知识
- 18、java随机访问RandomAccessFile类
- 手机短号 2081
- zoj 3480
- 懒加载异常
- Android 屏幕(View)坐标系统
- NEC的学习笔记