min()的宏定義中的(void) (&_x == &_y)的含義

Original Address:http://www.crifan.com/2010/08/13/order_min__macro_definition_void_amp__x__amp__y_the_meaning_of/
近日無意間發(fā)現(xiàn),關(guān)于常見的min的宏定義,在Linux中是這樣的:
關(guān)于其中的:
(void) (&_x == &_y);
很是疑惑,表面看起來,這句話,好像不起作用,算是一句廢話,所以去找了一下別人的解釋,才大概搞懂是啥意思。
首先,我們此處想要實現(xiàn)的目的是,在計算兩個數(shù)的最小值之前,希望去判斷一下兩個值的類型是否一致,而由于C語言本身不支持我們?nèi)プ鲱愃朴谶@樣的操作typeof(_x)==typeof(_y)
,
所以在此,通過故意判斷他們2個的地址指針是否相等,而顯然&_x,即x的地址,是不可能等于&_y的,但是這句話(void) (&_x == &_y);
使得,如果_x和_y的類型不一樣,其指針類型也會不一樣,2個不一樣的指針類型進行比較操作,則會引起編譯器產(chǎn)生一個編譯警告,提示你這兩個值的類型不同。
比如,如果你編譯下面這段代碼:
int x = 2;
char y = 3;
int m;
m = min(x,y);
編譯的時候,經(jīng)過預(yù)處理后,就會有這樣的判斷操作:
int * == char *;
因此編譯器就會提示你:
warning: comparison of distinct pointer types lacks a cast
所以,這個宏的巧妙之處就在于此。
所以,總結(jié)起來就是:
(void) (&_x == &_y); 用于判斷輸入的兩個值的類型是否是一致的。
如果不一致,那么編譯器就會做出如下警告:warning: comparison of distinct pointer types lacks a cast
提示
1. 其實關(guān)于min的宏,更好的做法是再加個const,即:
2. (void) (&_x == &_y); 中的void
,表示將表達式(&_x == &_y);
?所得到的結(jié)果(此處肯定是邏輯上的假,值為0)忽略掉。如果不加void,則會提示你這行代碼是無意義的,沒人用到。
3. 關(guān)于min的宏定義,為何這么復(fù)雜,而不是用簡單的#define min(x,y) ((x) < (y) ? x : y)
因為,如果如此定義,那么對于一些特殊的值傳入此宏之后,就會產(chǎn)生一些副作用,產(chǎn)生的結(jié)果,就不是我們想要的了,比如:
min(++a,++b) ==> ((++a)<(++b))?(++a) : (++b)
就使得,a++和b++分別執(zhí)行了2次,而且min的結(jié)果,也不對了。而用上面那個復(fù)雜的定義,多加了局部變量_x和_y,就可以避免此類問題了。
引用
(void) (&_x == &_y);
http://hi.baidu.com/huahua9901/blog/item/9640223f2a37773470cf6cc4.html
如下的宏定義中(void) (&_x == &_y);是怎么做到判斷類型的?
http://linux.chinaunix.net/bbs/viewthread.php?tid=1161263
Linux內(nèi)核中的Min和Max函數(shù)
http://www.armfans.net/thread-1527-1-1.html
防君子不防也無法防小人的聲明:
如未注明轉(zhuǎn)載則均為crifan原創(chuàng),對于原創(chuàng)文章,轉(zhuǎn)載請注明出處:在路上 - on the way
本文鏈接:【整理】min()的宏定義中的(void) (&_x == &_y)的含義