1. 程式人生 > >核心程式碼巨集中 do{...}while(0) 的作用

核心程式碼巨集中 do{...}while(0) 的作用

在核心空間非常有限的情況下,為什麼還要在某些巨集裡增加 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)並進行優化,所以使用這種方法也不會導致程式的效能降低。