C/C++宏定義中 do{...}while(0)用法分析
在許多C/C++宏定義中我們會(huì)看到宏代碼包含在do while循環(huán)或者if else語(yǔ)句里,例如:
? #define M(X) do { f(X); g(X); } while (0)
? #define M(X) if (1) { f(X); g(X); } else
那么這種用法有什么好處呢?這種用法最大的好處是增強(qiáng)宏定義代碼的魯棒性,盡管使得程序稍稍變得更加復(fù)雜。為了加快項(xiàng)目開(kāi)發(fā)進(jìn)度,現(xiàn)在一個(gè)工程的開(kāi)發(fā)越來(lái)越需要相互合作與溝通交流,不管是利用別人的代碼庫(kù)還是寫(xiě)一些頭文件供別人調(diào)用,都需要程序能夠按照編程者的意圖運(yùn)行。但是對(duì)于這里提到的宏定義來(lái)說(shuō),你并不知道別人會(huì)怎么使用你的宏,如果定義不合理就會(huì)出現(xiàn)一些問(wèn)題,例如下面這個(gè)宏定義:
? #define M(X) f(x); g(x)
如果你這樣使用這個(gè)宏:
? if (condition)
? ?M(x);
? else
? ?F();
宏展開(kāi)時(shí)會(huì)變成:
? if (condition)
? ?f(x); g(x);
? else
? ?F();
這樣就會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤,因?yàn)閑lse找不到對(duì)應(yīng)的if語(yǔ)句。如果給宏添加一個(gè)大括號(hào),則變成:
? if (condition)
? ?{f(x); g(x);};
? else
? ?F();
這樣也會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤,因?yàn)榇罄ㄌ?hào)后多了分號(hào)。針對(duì)這個(gè)問(wèn)題,可以利用do while(0)或者if else來(lái)解決,例如:
? #define M(X) ?do { f(X); g(X); } while (0)
或者:
? #define M(X) ?if (1) { f(X); g(X); } else
這樣調(diào)用后宏展開(kāi)成:
? if (condition)?
? do { f(X); g(X); } while (0);
? else
? ?F();
或者:
? if (condition)?
? if (1) { f(x); g(x); } else;
? else
? ?F();
這種方式利用了分號(hào)在代碼中的作用,可以有效克服C預(yù)處理器的一些缺點(diǎn)。有些編程指南告訴你要減少使用預(yù)處理器,這里提到的一點(diǎn)就是他們擔(dān)心的一個(gè)原因。當(dāng)然對(duì)于這種情況,你也可以把M(x)單獨(dú)定義為一個(gè)函數(shù),而不是一個(gè)宏。最后需要注意的一點(diǎn)是宏定義要寫(xiě)在一行,跨行需要加反斜杠''。