2010年8月11日 星期三

do{} while(0) 用法

轉自酷!學園

首先 inline 只有 c++ 才有,linux kernel source 基本上不大可能使用 inline 方式語法,只能夠使用 define 這類 c 與 c++ 都可以支援方式。

define 的許多問題我想大家應該知道,常見像是:

程式碼:
#define sq(a) (a*a)

這表示自己次方,一般使用上沒問題,像是:

程式碼:
int answer = sq(5); // 答案是 25

但是這樣用就死了...

程式碼:
int answer = sq(5+1) // 答案不是 36 啊.....

因為實際上是 5+1 * 5+1 ==> 5+5+1 = 11

所以要改成:

程式碼:
#define sq(a) ((a)*(a))

在 inline 內這類問題都不會發生就是...

拉回來,至於你說的問題....

程式碼:
#define function(x) do{...}while(0)

這寫法也是有特殊的意義,記得應該是 linux kernel FAQ 有寫.

程式碼:
#define swap(x,y) { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; }

但是這樣使用遇到這種情況會有問題:

程式碼:
if ( x > y )
  swap(x,y);
else
  otherthing();

但是程式碼展開就會....

程式碼:
if ( x > y )
   { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; };
else
  otherthing();

有無看到問題點?

程式碼:
if ( x > y ) {
   int tmp_n ;
   tmp_n = x
   x = y
   y = tmp_n;
  }
; <---- 這邊多分號,慘了 ~~~~
else
  otherthing();

這導致會編譯錯誤,因為 else 算是多出來的,已經不是與 else 配對的...

基於這個原因,所以才引入 function(x) do{...}while(0) 來解決

#define swap(a,b) do { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; } while(0)

那展開使用就是

程式碼:
if ( x > y )
   do {
                int tmp_n ;
                tmp_n = x;
                x = y;
                y = tmp_n;
          } while(0);
else
  otherthing();

這樣就不會出包了....

沒有留言:

張貼留言