linux do{} while(0)
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)
do{ free(p); p = NULL; } while(0);
else
.../*do something*/
不會再出現編譯問題。 do{ } while(0)的使用完全是為了保證宏定義的使用者能無編譯錯誤的使用宏,不對使用者做任何假設
linux do{} while(0)