宏函數爲什麼使用do{...}while{0}包起來

在我們看內核源碼或者庫以及一些優秀的源碼時,都會發現他們的宏函數是包括在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)其實並不是額外加了什麼功能,只是爲了保持宏函數實現的時候語意和我們所寫的代碼一致,防止大括號以及分號的干擾。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章