【问题标题】:Proper C preprocessor macro no-op正确的 C 预处理器宏无操作
【发布时间】:2012-07-18 19:51:26
【问题描述】:

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

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

尽管我的快速测试表明,在该行中生成的分号本身将用作条件内的无操作语句。

nothingdo {} while (0) 哪个更好?如果是这样,为什么?还有什么更好的吗?

【问题讨论】:

标签: c macros c-preprocessor


【解决方案1】:

分号本身有两个缺点:

  • 您的宏的用户可以不用分号编写它,编译器不会报错,并且
  • 某些编译器可能会发出关于可能杂散分号的警告。

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

DLOG("foo") // No semicolon

会触发一个错误,编译器不会警告你有一个“杂散”分号。

【讨论】:

    【解决方案2】:

    请参阅C #define macro for debug printing,了解为什么您需要不同形式的无操作。你想让编译器解析调试打印代码,即使你不使用它,这样错误就不会蔓延。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-09
        • 1970-01-01
        • 2011-01-26
        • 1970-01-01
        • 2019-06-26
        • 2016-03-20
        • 1970-01-01
        • 2012-11-16
        相关资源
        最近更新 更多