2012-07-18 77 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 

会触发一个错误,并且编译器不会警告你一个“流浪”分号。