Linux内核代码中有很多比较精巧的程序设计技巧,include/linux/kernel.h中实现max和min宏就是其中的一部分。
我们先来看一下普通的max和min一般怎么写:
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)>(y)?(x):(y))
但这么写有一个小风险,请看以下调用:
int x = 2;y = 1
printf("%d/n", max(x++, y++));
调用结束后会发现,x被加了2,主要是因为max被展开后如下:
((x++) > (y++) ? (x++) : (y++))
很明显,这么做是不安全的,那我们来看Linux Kernel是如何做的:
#define max(x, y) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
这么做主要涉及以下几个知识点:
1、typeof(x)
找出x的数据类型
2、语句表达是({S1;S2;...;Sn;})
总的语句表达是的值是Sn,这个技巧我之前写代码是也用到过,呵呵
3、(void) (&_x == &_y);的巧妙
这个主要是用来判断x,y数据类型是否一样,利用了编译器的一个小特性:不同数据类型的变量进行比较时会产生Warning,如果Makefile比较严格的话,会产生Error
关于这一点,很多人写,但都没写到点子上,以下几篇都很好:
http://www.armfans.net/thread-1527-1-1.html
收藏于 2013-09-07
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。