從min&max一窺linux設(shè)計
好吧,我承認我標題黨了。但是我仍然建議你能夠繼續(xù)往下讀,最多花上一分鐘時間。
當然,如果能夠浪費你十分鐘以上,我的目的便達到了,而你也會有不一樣的體會。 問題:你會怎樣實現(xiàn)min & max這兩個函數(shù)呢?
我想大多數(shù)人的做法無非三種:1)定義宏;2)定義函數(shù); 3)定義inline函數(shù)。
對于第二種方法,不用多說,功能如此單一的函數(shù)效率會有折扣;對于第三種方法,inline是在較新的C99中引入的。其實我是在找理由,我太懶了,不想討論第二種和第三種,也是在掩飾現(xiàn)代編譯器強悍的優(yōu)化能力。也許,編譯器自動為你把小函數(shù)優(yōu)化成內(nèi)聯(lián)了呢。OK,我們這里的主題是關(guān)于宏定義的,和其他無關(guān)。請看(下文都以min為例):
www.2cto.com
1
#define min(X,Y) ((X) < (Y) ? (X) : (Y))
這是一般的做法,對每個符號都還添加了括號處理,是比較讓人滿意的了。會有什么問題呢,繼續(xù)請看:
1
int x = 1, y = 2;
2
printf("min=%d/n", min(x++, y++)); //輸出min=2
3
printf("x = %d, y = %d/n", x, y); //輸出x=3, y=3
問題出現(xiàn)了,我們原本預(yù)期執(zhí)行min操作后,x為2,y為3。到底發(fā)生了什么呢,讓我們對宏進行展開:
1
((x++) < (y++) ? (x++) : (y++))
看出來了嗎?問題就出在這里,x++被執(zhí)行了兩次。讓我們看看偉大的linux內(nèi)核是怎么解決這個問題的吧。
01
//include/linux/kernel.h
02
03
#define min(x,y) ({ /
04
typeof(x) _x = (x); /
05
typeof(y) _y = (y); /
06
(void) (&_x == &_y); /
07
_x < _y ? _x : _y; })
08
09
#define max(x,y) ({ /
10
typeof(x) _x = (x); /
11
typeof(y) _y = (y); /
12 www.2cto.com
(void) (&_x == &_y); /
13
_x > _y ? _x : _y; })
我在這里進行簡單的解釋:
1)typeof(X)的用途:得到X的類型信息。比如typeof(10) 為int, double f = 1.0; typeof(f)為double。
2)({})的用途:一句話,({和})之間可以有很多表達式,它的值為最后一個表達式的值。
3)(void) (&_x == &_y);這一句的作用是對_x和_y的類型判斷是否一樣。如果是不同的類型,編譯器會給出警告信息。
說白了,上述宏定義就是先引入和x及y同樣類型的兩個臨時變量,然后對臨時變量進行求最大值或者最小值。
|
|
來自: rookie > 《技術(shù)帖》