C語言--min的宏定義

近日無心間發現,關於常見的min的宏定義,在Linux中是這樣的:php

  1. /* 
  2. * min()/max()/clamp() macros that also do 
  3. * strict type-checking.. See the 
  4. * "unnecessary" pointer comparison. 
  5. */  
  6. #define min(x, y) ({     \  
  7. typeof(x) _x = (x);    \  
  8. typeof(y) _y = (y);    \  
  9. (void) (&_x == &_y);   \  
  10. _x < _y ? _x : _y; })  

關於其中的:html

  1. (void) (&_x == &_y);  

非常疑惑,表面看起來,這句話,好像不起做用,算是一句廢話,因此去找了一下別人的解釋,才大概搞懂是啥意思。linux

首先,咱們此處想要實現的目 的是,在計算兩個數的最小值以前,但願去判斷一下兩個值的類型是否一致,而因爲C語言自己不支持咱們去作相似於這樣的操做 typeof(_x)==typeof(_y),因此在此,經過故意判斷他們2個的地址指針是否相等,而顯然&_x,即x的地址,是不可能等於& amp;_y的,可是這句話(void) (&_x == &_y);使得,若是_x和_y的類型不同,其指針類型也會不同,2個不同的指針類型進行比較操做,則會引發編譯器產生一個編譯警告,提示 你這兩個值的類型不一樣。函數

好比,若是你編譯下面這段代碼:spa

  1. int x = 2;  
  2. char y = 3;  
  3. int m;  
  4. m = min(x,y);  

編譯的時候,通過預處理後,就會有這樣的判斷操做:.net

int * == char *;unix

所以編譯器就會提示你:指針

warning: comparison of distinct pointer types lacks a casthtm

因此,這個宏的巧妙之處就在於此。blog

因此,總結起來就是:

【提示】

1。其實關於min的宏,更好的作法是再加個const,即:

  1. #define min(x, y) ({ \  
  2. const typeof(x) _x = (x); \  
  3. const typeof(y) _y = (y); \  
  4. (void) (&_x == &_y); \  
  5. _x < _y ? _x : _y; })  

2。(void) (&_x == &_y); 中的void,表示將表達式(&_x == &_y); 所獲得的結果(此處確定是邏輯上的假,值爲0)忽略掉。若是不加void,則會提示你這行代碼是無心義的,沒人用到。

3。關於min的宏定義,爲什麼這麼複雜,而不是用簡單的#define min(x,y) ((x) < (y) ? x : y)

由於,若是如此定義,那麼對於一些特殊的值傳入此宏以後,就會產生一些反作用,產生的結果,就不是咱們想要的了,好比:

  1. min(++a,++b) ==> ((++a)<(++b))?(++a) : (++b)   
就使得,a++和b++分別執行了2次,並且min的結果,也不對了。而用上面那個複雜的定義,多加了局部變量_x和_y,就能夠避免此類問題了。

【引用】

1。(void) (&_x == &_y);

2。以下的宏定義中(void) (&_x == &_y);是怎麼作到判斷類型的?

http://linux.chinaunix.net/bbs/viewthread.php?tid=1161263

3。Linux內核中的Min和Max函數

http://www.armfans.net/thread-1527-1-1.html

相關文章
相關標籤/搜索