2012-07-18 73 views
5

對於調試日誌,我經常看到並使用類似恰當的C預處理宏無操作

#ifdef DEBUG 
    #define DLOG(fmt, args...) printf("%s:%d "fmt,__FILE__,__LINE__,args) 
#else 
    #define DLOG(fmt, args...) 
#endif 

,但在一些地方,我看到換成第二#define

#define DLOG(fmt, args...) do {} while (0) 

特別是有this answer,並且對同一問題的this other answer的評論表明問題將出現在如下情況中:

if (condition) 
    DLOG("foo"); 

儘管我的快速測試表明,由此產生的分號本身將作爲條件內的no-op語句。

是一個或另一個沒有do {} while (0)更好?如果是這樣,爲什麼?還有什麼更好的嗎?

+0

[do {...} while(0)它有什麼好處?](http://stackoverflow.com/questions/257418/do-while-0-what-is-it-good -對於) – 2012-07-18 19:54:54

回答

5

請參閱C#define macro for debug printing以解釋爲什麼您需要不同形式的no-op。你想擁有編譯器,當你不使用它,甚至解析調試打印代碼,這樣的錯誤不蠕變

0

快速的回答是,do/while方法可以讓你有一個多語句替換,並且在if的情況下仍然可以像你在你的問題中一樣使用它作爲單個語句。對於單個表達式替換,我不認爲有任何區別。

7

本身分號有兩個缺點:

  • 宏罐頭的用戶編寫它沒有分號,並且編譯器不會抱怨,並且
  • 某些編譯器可能會發出有關可能的分號分號的警告。

do {} while (0)招解決了這兩個擔憂:

DLOG("foo") // No semicolon 

會觸發一個錯誤,並且編譯器不會警告你一個「流浪」分號。