Chinaunix首页 | 论坛 | 博客
  • 博客访问: 228411
  • 博文数量: 36
  • 博客积分: 482
  • 博客等级: 下士
  • 技术积分: 290
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-03 12:14
个人简介

Hi-ho, Silver! 在一个商业英雄辈出的年代,让我们用技术做一次华丽的冒险。向Linus致敬,向Stallman致敬!

文章分类

全部博文(36)

文章存档

2013年(24)

2012年(1)

2011年(8)

2010年(3)

我的朋友

分类: LINUX

2011-10-23 21:16:18

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) 
它所实现的功能与上面所述的相同,只是由编译器而非程序来实现罢了。



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

whyliyi2011-10-24 13:40:53

恩,linux里边这个做的很经典!很强大!