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

Isa*_*aac 7 c macros c-preprocessor

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

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

但在很多地方,我看到第二个#define被替换了

#define DLOG(fmt, args...) do {} while (0)
Run Code Online (Sandbox Code Playgroud)

特别是,有这个答案,对同一问题的另一个答案的评论表明,问题将出现在像

if (condition)
    DLOG("foo");
Run Code Online (Sandbox Code Playgroud)

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

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

das*_*ght 8

分号本身有两个缺点:

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

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

DLOG("foo") // No semicolon
Run Code Online (Sandbox Code Playgroud)

将触发错误,编译器不会警告您有关"杂散"的分号.


Jon*_*ler 5

有关调试打印的详细信息,请参阅C#define宏,以获取有关为何需要其他形式的无操作的说明.您希望编译器解析调试打印代码,即使您不使用它也不会出现错误.