2010年8月11日 星期三
do{} while(0) 用法
轉自酷!學園
首先 inline 只有 c++ 才有,linux kernel source 基本上不大可能使用 inline 方式語法,只能夠使用 define 這類 c 與 c++ 都可以支援方式。
define 的許多問題我想大家應該知道,常見像是:
這表示自己次方,一般使用上沒問題,像是:
但是這樣用就死了...
因為實際上是 5+1 * 5+1 ==> 5+5+1 = 11
所以要改成:
在 inline 內這類問題都不會發生就是...
拉回來,至於你說的問題....
這寫法也是有特殊的意義,記得應該是 linux kernel FAQ 有寫.
但是這樣使用遇到這種情況會有問題:
但是程式碼展開就會....
有無看到問題點?
這導致會編譯錯誤,因為 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)
那展開使用就是
這樣就不會出包了....
首先 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();
swap(x,y);
else
otherthing();
但是程式碼展開就會....
程式碼:
if ( x > y )
{ int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; };
else
otherthing();
{ 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();
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();
do {
int tmp_n ;
tmp_n = x;
x = y;
y = tmp_n;
} while(0);
else
otherthing();
這樣就不會出包了....
Memory Barrier
Memory Barrier
static inline void barrier(void) { asm volatile("": : : "memory"); }
格式 : __asm__(組合語言:輸出:輸入:修飾詞") __volatile__ 代表這行指令(這些組合語言),不和前面的指令一起最佳化。 "memory" 告訴GCC這些組合語言會改變所有的RAM的資料。 因為沒組合語言,又告訴gcc所有RAM的內容都改變,所以這個memory barrier的效用,會讓這行之前被gcc所cache到暫存器的資料通通寫回RAM裡面,也告訴gcc會讓之後讀取RAM的資料,必須再從RAM裡讀取出來。
訂閱:
文章 (Atom)