分类: LINUX
2010-03-14 14:58:09
#define list_entry(ptr, type, member) container_of(ptr, type, member)
container_of宏定义在[include/linux/kernel.h]中:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
offsetof宏定义在[include/linux/stddef.h]中:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
1.
(type *)0)->member 为什么要是0?
2 .
() 这个对括号不能少,是GNU的扩展
可以参考:http://nathanxu.blog.51cto.com/50836/6027 这篇文章的解释
在gnu c 中,用括号将复合语句括起来也形成了表达式。他允许你在一个表达式内使用循环,跳转和局部变量。
一个复合语句是用大括号{}括起来的一组语句。在包含语句的表达式这种结构中,再用括号( )将大括号括起来,
例如:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
就是一个合法表达式,用于计算foo( )函数返回值的绝对值。
在上面的复合语句中,最后的一句必须是一个以分号结尾的表达式。这个表达式代表了整个结构的值。
如果你在大括号里的最后一句用的是其他的语句,则整个结构的返回类型为void,即没有合法的返回值。
这种特性使得宏定义变得更加安全(因为每个操作数都只被计算一次,例如++运算)。例如计算最大值通常在
c语言中被定义为这样的宏:
#define max(a,b) ((a) > (b) ? (a) : (b))
但是其中的a和b可能会被计算两次,如果操作数带有副作用,则会产生错误的结果。在gnu c中,
如果你知道了操作数的类型(假设为int),你可以这样安全的定义宏:
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
语句内嵌在常量表达式(例如枚举类型),位域尺寸或静态变量初始化中是不允许的。如果你不知道操作数
的类型,你也可以使用typeof来获得类型。语句表达式内嵌在g++中并不支持,而且将来是否支持目前也
不清楚(他们在某时被完全支持或者被抛弃掉,或者作为bug会一直存在)。就目前而言,语句内嵌表达式
在默认情况下工作的并不好。