链表的container_of 疑惑

内核中container_of定义如下:

#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})


第二行好像没用,可以直接这样定义:
#define container_of(ptr, type, member) ( (type *)( (char *)(ptr) - offsetof(type,member) ) )

而在2.4的内核中的确是这么写的。

 

关于原因:

 

当参数会用到多次时,没有第2行会有副作用。
比如
#define min(x,y) ((x) < (y) ? (x) : (y))
当调用时用的是min(a++,b++)的时候,a和b的值就不对了(可能加了两次)。

#define min_t(type,x,y) \
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
就没有这个问题。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

语句表达式
==========

GNU C 把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出
现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本
只能在复合语句中使用。例如:

++++ include/linux/kernel.h
159: #define min_t(type,x,y) \
160: ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
++++ net/ipv4/tcp_output.c
654: int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk));

复合语句的最后一个语句应该是一个表达式,它的值将成为这个语句表达式的值。
这里定义了一个安全的求最小值的宏,在标准 C 中,通常定义为:

#define min(x,y) ((x) < (y) ? (x) : (y))

这个定义计算 x 和 y 分别两次,当参数有副作用时,将产生不正确的结果,使用
语句表达式只计算参数一次,避免了可能的错误。语句表达式通常用于宏定义。

posted @ 2012-09-06 09:09  天地不仁  阅读(318)  评论(0编辑  收藏  举报