在我們看內核源碼或者庫以及一些優秀的源碼時,都會發現他們的宏函數是包括在do{…}while(0)內。具體的原因其實想想就能明白。
考慮下面一個特殊的例子。
宏函數的定義如下:
#define test(x) \
a(x); \
b(x);
如果在調用時是這樣調用的:
if (judge)
test(x);
那麼展開之後就是:
if (judge):
a(x);
b(x);
這時產生的效果可能就和你的本意不同了,因爲b(x)無論怎樣都會執行。
這是由於大括號產生的問題,那如果我們簡單的給宏函數加上大括號而不用do{…}while(0)可以嗎?
舉例如下:
#define test(x)\
{ \
a(x);\
b(x);\
}
調用時:
if (judge)
test(x);
展開之後:
if (judge)
{
a(x);
b(x);
};
這個時候就產生語法錯誤了,因爲多了一個分號。
總結:宏函數加do{…}while(0)其實並不是額外加了什麼功能,只是爲了保持宏函數實現的時候語意和我們所寫的代碼一致,防止大括號以及分號的干擾。