Linux內核中的do{}while(0)

 

Linux內核中的do{}while(0)
     在Linux內核中,經常會看到do{}while(0)這樣的語句,剛開始會疑惑,認爲do{}while(0)毫無意義,因爲它只會執行一次,加不加do{}while(0)效果是完全一樣的,其實do{}while(0)只要用於宏定義中。
     這裏用以個簡單點的宏來演示:
 #define SAFE_FREE(P)   do{free(p); p = NULL;}while(0)
     假設這裏去掉do{}while(0),即定義SAFE_FREE爲:
 #define SAFE_FREE(P)   free(p); p = NULL;
     那麼以下代碼:
  if(NULL!=P)
    SAFE_FREE(P)
  else
   ...// do something
    會被展開爲:
  if(NULL!=P)
   free(p); p = NULL;
  else
   ...// do something
    展開的代碼中存在兩個問題:
 (1)if分支後有兩個語句,導致else分支沒有對應的if,編譯失敗;
 (2)假設沒有else分支,則SAFE_FREE中的第二個語句無論if條件是否爲真都會被執行。
   將SAFE_FREE的第定義加上{}就可以解決上述問題了,即:
   #define SAFE_FREE(P)   {free(p); p = NULL;}
    這樣,代碼:
  if(NULL!=P)
   SAFE_FREE(P)
  else
   ...// do something
    會被展開爲:
  if(NULL!=P)
   {free(p); p = NULL;}
  else
   ...// do something
    但是,在C語言中,每個語句後面加個分號是一種約定俗成的習慣,那麼,如下代碼:
  if(NULL!=P)
   SAFE_FREE(P);
  else
   ...// do something
   將被展開爲:
  if(NULL!=P)
   {free(p); p = NULL;};
  else
   ...// do something
    這樣,else分支就又沒有對應的if了,編譯將無法通過。假設用了do{}while(0),情況就不一樣了,同樣的代碼就會被展開爲:
 if(NULL!=P)
   {free(p); p = NULL;}
  else
   ...// do something
   不會在出現編譯問題。  do{}while(0)的使用完全是爲了保證宏定義的使用者能無編譯錯誤的使用宏,它不對其使用者做任何假設。

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章