list_entry(p, t, m)详解

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

相关资料:

list_entry(p, t, m)详解来源网络,如有侵权请告知,即处理!

编程Tags: