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) );})
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)
它所实现的功能与上面所述的相同,只是由编译器而非程序来实现罢了。
阅读(695) | 评论(0) | 转发(0) |