下面這個DUMP_WRITE定義,使用了do...while(0):
#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
do...while(0)是先執行後判斷的,那這邊使用這個的作用是什麼?
do-while循環是先執行後判斷循環條件。所以,這個定義意味着每當引用這個宏 操作時會執行循環體一次,而且只執行一次。可是,爲什麼要這樣通過一個do-while循環來定義呢? 這似乎有點怪。我們不妨看看其它幾種可能。首先,能不能定義成如下式樣?
#define DUMP_WRITE(addr,nr) memcpy(bufp,addr,nr); bufp += nr;
不行。如果有一段程序在一個if語句中引用這個宏操作就會出問題,讓我們通過一個假想的例子 來說明:
if(addr)
DUMP_WRITE(addr,nr);
else
do_something_else();
經過預處理以後,這段代碼就會變成這樣:
if(addr)
memcpy(bufp,addr,nr); bufp += nr; else
do_something_else();
你也許馬上會想到要在定義中加上花括號,成爲這樣:
#define DUMP_WRITE(addr,nr) {memcpy(bufp,addr,nr); bufp += nr;}
可是,上面那段程序還是通不過編譯,因爲經過預處理就變成這樣:
if(addr)
{memcpy(bufp,addr,nr); bufp += nr;}; else
do_something_else();
同樣,gcc在碰到else前面的“;’’時就認爲if語句已經結束,因而後面的else不在if語句中。相 比之下,採用do-while的定義在任何情況下都沒有問題。
--------------------------------------------------------------------------
注:以上示例摘自《Linux內核源代碼情景分析》