在 Linux 內核中,經常會看到do{} while(0)這樣的語句,許多人開始都會疑惑,認為do{} while(0)毫無意義,因為它只會執行一次,加不加do{} while(0)效果是完全一樣的,其實do {}while(0)的用法主要用于宏定義中。
這里用一個簡單的宏來演示:
#defineSAFE_FREE(p)do{free(p);p=NULL;}while(0)
假設這里去掉do...while(0),即定義SAFE_DELETE為:
#defineSAFE_FREE(p)free(p);p=NULL;
那么以下代碼:
if(NULL!=p) SAFE_DELETE(p) else .../*dosomething*/
會被展開為:
if(NULL!=p) free(p);p=NULL; else .../*dosomething*/
展開的代碼中存在兩個問題。
(1)、因為 if 分支后有兩個語句,導致 else 分支沒有對應的 if,編譯失敗。
(2)、假設沒有 else 分支,則 SAFE_FREE 中的第二個語句無論 if 測試是否通過,都會執行。
的確,將SAFE_FREE的定義加上{}就可以解決上述問題了,即:
#defineSAFE_FREE(p){free(p);p=NULL;}
這樣,代碼:
if(NULL!=p) SAFE_DELETE(p) else .../*dosomething*/
會被展開為:
if(NULL!=p) {free(p);p=NULL;} else .../*dosomething*/
但是,在 C 程序中,每個語句后面加分號是一種約定俗成的習慣,那么,如下代碼:
if(NULL!=p) SAFE_DELETE(p); else .../*dosomething*/
將被擴展為:
if(NULL!=p) {free(p);p=NULL;}; else .../*dosomething*/
這樣,else 分支就又沒有對應的 if 了,編譯將無法通過。假設用了do {} while(0),情況就不一樣了,同樣的代碼會被展開為:
if(NULL!=p) do{free(p);p=NULL;}while(0); else .../*dosomething*/
不會再出現編譯問題。do while(0)的使用完全是為了保證宏定義的使用者能在不出現編譯錯誤的情況下使用宏,它不對其使用者做任何假設。
審核編輯:劉清
-
C語言
+關注
關注
180文章
7604瀏覽量
136692 -
LINUX內核
+關注
關注
1文章
316瀏覽量
21644
原文標題:C語言-宏定義中使用do {...} while(0)到底圖個啥
文章出處:【微信號:嵌入式那些事,微信公眾號:嵌入式那些事】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論