Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1673803
  • 博文数量: 782
  • 博客积分: 2455
  • 博客等级: 大尉
  • 技术积分: 4140
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-06 21:37
个人简介

Linux ,c/c++, web,前端,php,js

文章分类

全部博文(782)

文章存档

2015年(8)

2014年(28)

2013年(110)

2012年(307)

2011年(329)

分类:

2011-10-24 13:16:33

原文地址:list_entry(p, t, m)详解 作者:iicymaple

list_entry(p, t, m)详解


list_entry(p, t, m)是在include/linux/list.h中的宏定义:
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)

container_of(ptr, type, member)是在include/linux/kernel.h中定义:
#define container_of(ptr, type, member) ({        \
const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
(type *)( (char *)__mptr - offsetof(type,member) );})

其中,typeof关键字是C语言中的一个新扩展,用于获取类型。此处即获取member属性在type结构体中的类型名。具体使用可参考该连接:http://blog.chinaunix.net/space.php?uid=22145625&do=blog&id=1789481

offsetof(type,member)是在include/linux/stddef.h中定义:
#undef offsetof
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

解析:
此处(TYPE *)0强制轮换为TYPE *类型的指针,就像TYPE * ps = (TYPE *)0,ps的值为0,即指向的地址为0。那么&(ps->MEMBER)取出MEMBER变量的实际地址,因为ps指向地址为0的TYPE结构,所以就自然得出MEMBER的偏移地址了。

__compiler_offsetof在include/linux/compiler-gcc3.h中定义:
#define offsetof(type, member) __builtin_offsetof (type, member) 
它所实现的功能与上面所述的相同,只是由编译器而非程序来实现罢了。



阅读(659) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~