Chinaunix首页 | 论坛 | 博客
  • 博客访问: 411975
  • 博文数量: 36
  • 博客积分: 960
  • 博客等级: 准尉
  • 技术积分: 1368
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-13 19:26
文章分类
文章存档

2018年(3)

2012年(6)

2011年(27)

分类: LINUX

2011-11-25 18:23:44

-------------------------------------------
本文系作者原创, 欢迎大家转载!
转载请注明出处:netwalker.blog.chinaunix.net
-------------------------------------------
 
由于Linux代码采用Gcc编译器编译,所以它可以采用Gcc对C语言的扩展特性,以实现高效的代码。其中运用非常广泛的扩展就是复合语句。Gcc把包含在圆括号和大括号双层括号内的复合语句看作是一个表达式,它可以出现在任何允许表达式的地方,而复合语句中可以声明局部变量,以及循环条件判断等复杂处理。而表达式的最后一条语句必须是一个表达式,它的计算结果作为返回值。
  1. int a = ({typeof(a) _a = 0; ++_a;});

上例中符合表达式中声明了局部变量_a,而返回值为++_a的结果,所以a的值为1。基于这种扩展,内核可以通过在复合语句中定义局部变量而表面自加自减运算符的副作用问题。内核中的min_t和max_t宏就是这样实现的。

  1. include/linux/kernel.h
  2. #define min_t(type, x, y) ({            \
  3.     type __min1 = (x);            \
  4.     type __min2 = (y);            \
  5.     __min1 < __min2 ? __min1: __min2; })

  6. #define max_t(type, x, y) ({            \
  7.     type __max1 = (x);            \
  8.     type __max2 = (y);            \
  9.     __max1 > __max2 ? __max1: __max2; })

尽管多数时候通过使用这类宏,可以避免参数的副作用,但是这会增加内存的开销和执行效率,所以如果能够保证参数不存在副作用,那么使用通常的如下定义即可:

  1. #define min(a, b) ((a) > (b)? (b) : (a))
  2. #define max(a, b) ((a) > (b)? (a) : (b))

以上的min_t和max_t宏适需要提供数据类型,typeof的出现使这一步也可被省略。

  1. include/linux/kernel.h
  2. #define min(x, y) ({                \
  3.     typeof(x) _min1 = (x);            \
  4.     typeof(y) _min2 = (y);            \
  5.     (void) (&_min1 == &_min2);        \
  6.     _min1 < _min2 ? _min1 : _min2; })

  7. #define max(x, y) ({                \
  8.     typeof(x) _max1 = (x);            \
  9.     typeof(y) _max2 = (y);            \
  10.     (void) (&_max1 == &_max2);        \
  11.     _max1 > _max2 ? _max1 : _max2; })

观察min和max的实现,它们通过typeof获取x和y的类型,然后定义局部变量以消除参数副作用。注意到中间的比较运算,如果x和y的类型不同,那么编译器将提示如下警告信息,这对检查代码很有帮助。

  1. xxx.c:35: warning: comparison of distinct pointer types lacks a cast
阅读(2791) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~