适当的C预处理宏无操作

11

对于调试日志,我经常看到和使用类似以下的内容:

#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)

特别地,有这个答案,以及对于同一个问题的这个其他答案上的评论表明,问题可能出现在以下情况中:

if (condition)
    DLOG("foo");
尽管我的快速测试表明,单独一行的分号可以作为条件语句中的空操作语句。

问题:使用`nothing`和`do {} while (0)`哪个更好?如果有,请说明原因。还有其他更好的方法吗?

可能是do { ... } while (0)有什么用处?的重复问题。 - Carl Norum
3个回答

10

单独使用分号存在两个缺点:

  • 您的宏的用户可以不带分号编写它,编译器不会发出警告
  • 一些编译器可能会发出有关可能存在多余分号的警告。

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

DLOG("foo") // No semicolon

会触发一个错误,编译器不会警告你关于一个“迷途”的分号。


6

请参阅C #define macro for debug printing,了解为什么需要不同形式的no-op。在不使用调试打印代码时,您希望编译器也解析它,以防止出现错误。


0
快速的答案是,使用 do/while 方法可以让你拥有一个多语句替换,并且仍然可以像你在问题中所示的那样,在 if 语句中将其用作单个语句。对于单个表达式替换,我认为没有任何区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接