1. 程式人生 > 其它 >#define do{...}while(0)形式的意義(轉載)

#define do{...}while(0)形式的意義(轉載)

#define do{...}while(0)這種奇怪形式的巨集定義經常在實際工程中應用,它的意義如下:

1. 增加程式碼的適應性

下面的巨集定義沒有使用do{...}while(0)

#define FOO(x) foo(x); bar(x);

這樣巨集定義,單獨呼叫不會出現問題,例如:

FOO(100)

巨集擴充套件後變成:

foo(x);bar(x);

這樣呼叫FOO沒有任何問題,但是FOO(x)不能放入控制語句中,例如:

if (condition)
    FOO(x);
else
    ...;

經過巨集擴充套件後,變成了

if (condition)
    foo(x);bar(x);
else 
    ...;

這樣就導致了語法錯誤,語法錯誤並不可怕,在編譯階段就能發現,更致命的是他有可能導致邏輯錯誤,這種錯誤編譯器發現不了,一出這種問題,程式設計師就抓狂吧。例如:

if (condition)
    FOO(x);

這段程式碼經過擴充套件後變成:

if (condition)
    foo(x); bar(x);

這樣一來,無論condition是true還是false,bar(x)都會被呼叫。有沒有被這煎熬過的兄弟啊?

這時候do{...}while(0)的價值就體現出來了,修改一下FOO的定義

#define FOO(x) do { foo(x); bar(x); } while (0)

這樣FOO,放入控制語句中就沒有問題了。

也許有人說:把foo(x);bar(x)用大括號括起來不就行了嗎?比如這樣定義:

#define FOO(x) { foo(x); bar(x); }

再看下面程式碼:

if (condition)
    FOO(x);
else 
    ...;

擴充套件後:

if (condition)
    {foo(x);bar(x);} ; //注意最後這個分號,語法錯誤
else 
    ...;

照樣語法錯誤;

2.增加程式碼的擴充套件性

我理解的擴充套件性,主要是巨集定義中還可以引用其他巨集,比如:

#define FOO(x) do{OTHER_FOO(x)} while(0)
這樣我們不用管OTHER_FOO是但語句還是符合語句,都不會出現問題

3.增加程式碼的靈活性

靈活性主要體現在,我們可以從巨集中break出來,例如下面的定義:

#define FOO(x)  do{ \
    foo(x);  \
    if(condition(x)) \
        break; \
    bar(x) \
    ..... \} while(0)