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