小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

從一個簡單的宏定義看linux內(nèi)核的嚴謹,窺C語言的強大 min()

 WUCANADA 2012-05-30
從一個簡單的宏定義看linux內(nèi)核的嚴謹,窺C語言的強大
2010-12-17 21:13

 

最近閑來無事,分析下linux kernel里面一些函數(shù)都是怎樣定義使用的,它們都是怎樣避免風險的,從include/linux/kernel.h中挑出一個經(jīng)典的min宏進行分析一下

 

從我們最先認識的min函數(shù)開始看看,這個函數(shù)的作用就是求兩個數(shù)中小一點的那個

#define min(x, y) ({                                \

typeof(x) _min1 = (x);                        \

typeof(y) _min2 = (y);                        \

(void) (&_min1 == &_min2);                \

_min1 < _min2 ? _min1 : _min2; })

 

1)首先我們可以看到這個宏的定義外面由一個({}),為什么要這樣寫呢?其實{}很好理解,因為我們的宏是多個語句,假如沒有了這個{},在一些語句中就會出現(xiàn)歧義,比如 ifa minx,y),這樣就會出問題,后面的語句它就不會執(zhí)行了。那么這里為什么在外面還要加一個()呢,我們來看這個函數(shù)的作用,它是用來返回一個較小的數(shù),對,是返回,一般來說對于返回值,我們怎么用?最簡單的當然是return了,所以,一般來講,我們會寫return min(x,y);(當然還有很多常用的方法,比如說賦值等等,我這邊的目的只是解釋()呵呵~~)。這個時候你就不難理解我們?yōu)槭裁匆觽€()了吧,不過正規(guī)的來講,這是GCC擴展中的一個用法,在GCC擴展中允許吧一個()內(nèi)的復合語句看成是一個表達式,稱為語句表達式,它可以出現(xiàn)在任何語句表達式可以出現(xiàn)的地方。

2)繼續(xù)看這個宏,我們知道一般我們使用這個函數(shù)的時候,x,y是什么類型的并不清楚,我們是否需要所有的類型都寫一個min函數(shù)呢?其實不需要,在GCC的擴展中,我們提供了一個宏,稱為typeof,它可以獲得相應參數(shù)的類型,這樣就可以不需要因為類型而重寫宏了,小方便啊。

再看這兩句話:

typeof(x) _min1 = (x);                        \

typeof(y) _min2 = (y);                        \

為什么要把x,y賦值給_min1_min2然后返回_min1_min2,而不直接寫成(x) < (y)? (x) :(y)呢?這個就是最經(jīng)典的C語言課本中所說的那個所謂的++的問題了,還需要多說嗎?好吧,我說一下吧,因為我也是菜鳥,也記不清當時是在什么地方提到這個東西了,呵呵,不過印象中記得好像是這樣說的:假如我寫成min(a++,b++),展開成宏就變成了(a++ < (b++)? (a++) :(b++)了,究竟ab各自++了多少次,大概可以算出來吧,所以我們一定要先把它們賦值給兩個局部變量,這樣就沒有這個問題了。

3)下面再來看一下那個(void) (&_min1 == &_min2);這句話好糾結(jié)啊,奶奶的,反正我是沒看懂是什么作用,不過可以肯定的是肯定有它存在的意義,于是只好做試驗了,好吧,我寫寫寫,寫了好幾個代碼發(fā)現(xiàn)兩者都是一樣的,怎么辦呢?呵呵,google一下,終于發(fā)現(xiàn)有人講這個了,說是為了在比較不同類型的時候能夠打印一個警告信息。好吧,我試試看,寫一個簡單測試程序

#include <stdio.h>

 

#define min(x, y) ({                                \

typeof(x) _min1 = (x);                        \

typeof(y) _min2 = (y);                        \

(void) (&_min1 == &_min2);                \

_min1 < _min2 ? _min1 : _min2; })

 

main(){

unsigned long a = 4;

in b = 5;

 

printf("min is %d\n", min(a, b));

}

gcc編譯了一下,果然報下面警告了:

min.c: In function ‘main’:

min.c:14: 警告:比較不相關(guān)的指針時缺少類型轉(zhuǎn)換

沒有這句話,就不會報這個警告,為什么會這樣呢?跟阿虛討論了下,原來,在比較地址的時候,會發(fā)現(xiàn)地址所存值的類型,假如不同的話就會報警告,而在直接比較值的時候,比如上面的_min1 < _min2 ?的時候,會做強制類型轉(zhuǎn)換,而且不會報警告,好吧,我真的很佩服寫這段代碼的人,太牛了!簡單的4,5行代碼,竟然有這么多的東西在里面,這叫老夫如何是好啊,繼續(xù)努力。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多