适当的C预处理器宏无操作

时间:2012-07-18 19:51:26

标签: c macros c-preprocessor

对于调试日志记录,我经常看到并使用类似

的内容
#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 answerthis other answer对同一问题的评论表明问题出现在

之类的情况
if (condition)
    DLOG("foo");

虽然我的快速测试表明,行中产生的分号本身将作为条件内的无操作语句。

nothing do {} while (0)中的一个或另一个更好吗?如果是这样,为什么?还有其他更好的东西吗?

3 个答案:

答案 0 :(得分:8)

分号本身有两个缺点:

  • 宏的用户可以不用分号编写它,编译器不会抱怨,
  • 某些编译器可能会发出有关可能有偏移分号的警告。

do {} while (0)技巧解决了这两个问题:

DLOG("foo") // No semicolon

会触发错误,编译器不会警告你有关“流浪”的分号。

答案 1 :(得分:5)

请参阅C #define macro for debug printing,了解您希望使用其他形式的无操作的原因。您希望编译器解析调试打印代码,即使您没有使用它也不会出现错误。

答案 2 :(得分:0)

快速回答是do / while方法允许您进行多语句替换,并且仍然像if案例中那样将其用作单个语句,就像您在问题中一样。对于单个表达式替换,我认为没有任何区别。