2012-02-08 16 views
-1

我遇到定義的宏如下所示:c中的「do while」宏的優點?

#define CALL_FUNCS(x) 
do { 
    func1(x); 
    func2(x); 
    func3(x); 
} while (0); 

現在,當然這會工作這是怎麼回事任何比下面的版本更好?

#define CALL_FUNCS(x) 
{ 
    func1(x); 
    func2(x); 
    func3(x); 
} 

我認爲這不是關於宏觀優化。對此有何想法?

+0

C++常見問題解答[在此有一個很好的條目](http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.5) – 2012-02-08 20:17:43

+0

謝謝塞斯卡內基,找到了指針:http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.5 – 2012-02-09 05:30:19

+0

[C/C++宏中的Do-While和if-else語句]的可能重複(http ://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-cc-macros) – legoscia 2014-04-09 17:02:05

回答

4

該宏實際上不應該有最後的;如果出現錯誤,這是爲了在宏周圍獲得正常/更期望和有用的語法錯誤。

4

如果你沒有在if-else語句中使用do ... while (0)形式,你會得到一個錯誤:

if (bla) CALL_FUNCS(); 
else statement; 

將預處理爲:

if (bla) 
{ 
    func1(x); 
    func2(x); 
    func3(x); 
}; 
else statement; 

else語句之前分號是無效的。

注(由@arsenm指出的),你不應該把最終;do ... while (0)後的宏定義,你必須和使用\定義中的行之後:

#define CALL_FUNCS(x) \ 
do {     \ 
    func1(x);   \ 
    func2(x);   \ 
    func3(x);   \ 
} while (0) 
+0

@SethCarnegie,有兩個尾隨分號考慮。首先,宏的* definition *末尾有不正確的額外分號。但也看看如何使用宏; 'CALL_FUNCS(x);'中有一個分號,即使使用第二種形式,它也不會消失。 – 2012-02-08 20:24:38

0

這用於強制用戶在宏調用後添加;

3

首先,它不應該有尾隨;。應該是:

#define CALL_FUNCS(x) do { func1(x); func2(x); func3(x); } while (0) 

無論如何,原因如下。考慮

if(b) 
    CALL_FUNCS(x); 
else 
    something_else(x); 

這將擴展爲:

if(b) 
    { func1(x); func2(x); func3(x); }; 
else 
    something_else(x); 

現在我們仍然有一個trailling ;並會收到此錯誤信息:

error: ‘else’ without a previous ‘if’ 

注意,如果保持;在宏,那麼你將有兩個尾隨; s!

宏觀擴展應該看起來像是期待分號的東西。你不打字CALL_FUNCS(x),你打電話CALL_FUNCS(x);。你可以依靠do.. while(0)撇取分號,但{ }不會這樣做。