转载自 http://apps.hi.baidu.com/share/detail/45688930
作者:不详
近日无意间发现,关于常见的min的宏定义,在Linux中是这样的:
/*
* min()/max()/clamp() macros that also do
* strict type-checking.. See the
* "unnecessary" pointer comparison.
*/
#define min(x, y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
关于其中的:
(void) (&_x == &_y);
很是疑惑,表面看起来,这句话,好像不起作用,算是一句废话,所以去找了一下别人的解释,才大概搞懂是啥意思。
首先,我们此处想要实现的目的是,在计算两个数的最小值之前,希望去判断一下两个值的类型是否一致,而由于C语言本身不支持我们去做类似于这样的操作typeof(_x)==typeof(_y),所以在此,通过故意判断他们2个的地址指针是否相等,而显然&_x,即x的地址,是不可能等于&_y的,但是这句话(void) (&_x == &_y);使得,如果_x和_y的类型不一样,其指针类型也会不一样,2个不一样的指针类型进行比较操作,则会引起编译器产生一个编译警告,提示你这两个值的类型不同。
比如,如果你编译下面这段代码:
int x = 2;
char y = 3;
int m;
m = min(x,y);
编译的时候,经过预处理后,就会有这样的判断操作:
int * == char *;
因此编译器就会提示你:
warning: comparison of distinct pointer types lacks a cast
所以,这个宏的巧妙之处就在于此。
所以,总结起来就是:
(void) (&_x == &_y); 用于判断输入的两个值的类型是否是一致的。如果不一致,那么编译器就会做出如下警告:warning: comparison of distinct pointer types lacks a cast
【提示】
1。其实关于min的宏,更好的做法是再加个const,即:
- #define min(x, y) ({ \
- const typeof(x) _x = (x); \
- const typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x < _y ? _x : _y; })
2。(void) (&_x == &_y); 中的void,表示将表达式(&_x == &_y); 所得到的结果(此处肯定是逻辑上的假,值为0)忽略掉。如果不加void,则会提示你这行代码是无意义的,没人用到。
3。关于min的宏定义,为何这么复杂,为什么要在定义两个局部变量_x,_y,而不是用简单的#define min(x,y) ((x) < (y) ? x : y)
因为,如果如此定义,那么对于一些特殊的值传入此宏之后,就会产生一些副作用,产生的结果,就不是我们想要的了,比如:
min(++a,++b) ==> ((++a)<(++b))?(++a) : (++b)
就使得,a++和b++分别执行了2次,而且min的结果,也不对了。而用上面那个复杂的定义,多加了局部变量_x和_y,就可以避免此类问题了。
min和max 函数还能写为:
#define min(type , x , y) ({ type _x = (x) ; type _y = (y) ; _x < _y ? _x : _y; })
#define max(type , x , y) ({ type _x = (x); type _y =(y);_x > _y ? _x : _y; })
但是这样写就不太通用一些,还非要传个type参数。标准的用 typeof 更好的多。
另外,一个一直困扰你的问题,那个大括号是做什么的。
假如这样定义 #define min(type , x , y) ( type _x = (x) ; type _y = (y) ; _x < _y ? _x : _y; )
那么使用min时用语句:min( int , 2 , 3 ); 那么宏展开后,会多一个分号,编译器会报错。这就是为什么加那个大括号。
【引用】
1。(void) (&_x == &_y);
http://hi.baidu.com/huahua9901/blog/item/9640223f2a37773470cf6cc4.html
2。如下的宏定义中(void) (&_x == &_y);是怎么做到判断类型的?
http://linux.chinaunix.net/bbs/viewthread.php?tid=1161263
3。Linux内核中的Min和Max函数