核心程式碼巨集中 do{...}while(0) 的作用
阿新 • • 發佈:2018-11-01
在核心空間非常有限的情況下,為什麼還要在某些巨集裡增加 do{...}while(0) 這種“沒用”的程式碼行呢?
帶引數的巨集定義的一般形式為: #define <巨集名>(<引數表>) <巨集體> <巨集名>:一個識別符號 <引數表>:引數可以是一個或多個。多個引數之間用逗號分隔 <巨集體>:被替換用的字串,字串是由引數表中的各個引數組成的一個或多個表示式
*
巨集體在呼叫處直接展開
eg:#define N 2+3
int main ()
{
int n;
n = N*2;
printf ("%d", n);
return 0;
}
答案為8 (2+3*2=8)
假設有這樣一個巨集定義: #define exch(x,y) int tmp; tmp=x; x=y; y=tmp;
當我們這樣用的時候: if (x > y) exch(x,y); else do_something(); 根據巨集的用法,可得: if (x > y) int tmp; tmp = x; x = y; y = tmp; ; // empty statement else do_something(); 此時,語句tem = x; x = y; y = tmp;明顯不在if程式碼塊內。
如果直接在巨集定義處加上{},即: #define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
那確實是解決了上面的問題,可是還會出現新的問題: if (x > y) { int tmp; tmp = x; x = y; y = tmp; }; // empty statement else do_something();
error: ‘else’ without a previous ‘if’ else 前面的 ;表明之前已經是一個(段)完整的語句了,那麼接下來直接用 else 就有語法錯誤了
但是用上 do{...}while(0) 之後: if (x > y) do { int tmp; tmp = x; x = y; y = tmp; } while(0); else do_something();
為了儘量避免錯誤,使用do{….}while(0) 把程式碼塊包裹起來,成為一個獨立的語法單元,從而不會與上下文發生混 淆。絕大多數的編譯器都能夠識別do{…}while(0)並進行優化,所以使用這種方法也不會導致程式的效能降低。
帶引數的巨集定義的一般形式為: #define <巨集名>(<引數表>) <巨集體> <巨集名>:一個識別符號 <引數表>:引數可以是一個或多個。多個引數之間用逗號分隔 <巨集體>:被替換用的字串,字串是由引數表中的各個引數組成的一個或多個表示式
假設有這樣一個巨集定義: #define exch(x,y) int tmp; tmp=x; x=y; y=tmp;
當我們這樣用的時候: if (x > y) exch(x,y); else do_something(); 根據巨集的用法,可得: if (x > y) int tmp; tmp = x; x = y; y = tmp; ; // empty statement else do_something(); 此時,語句tem = x; x = y; y = tmp;明顯不在if程式碼塊內。
如果直接在巨集定義處加上{},即: #define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
那確實是解決了上面的問題,可是還會出現新的問題: if (x > y) { int tmp; tmp = x; x = y; y = tmp; }; // empty statement else do_something();
error: ‘else’ without a previous ‘if’ else 前面的 ;表明之前已經是一個(段)完整的語句了,那麼接下來直接用 else 就有語法錯誤了
但是用上 do{...}while(0) 之後: if (x > y) do { int tmp; tmp = x; x = y; y = tmp; } while(0); else do_something();
為了儘量避免錯誤,使用do{….}while(0) 把程式碼塊包裹起來,成為一個獨立的語法單元,從而不會與上下文發生混 淆。絕大多數的編譯器都能夠識別do{…}while(0)並進行優化,所以使用這種方法也不會導致程式的效能降低。