为什么 qCDebug() 宏是这样定义的?

时间:2021-07-02 07:26:25

标签: c++ qt coding-style

qCDebug() 宏有一个简单的声明,但是使用“退化 for-loop”而不是简单直接的 if 有什么好处?

    #define qCDebug(category, ...) \
        for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
            QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__)

现代编译器在优化高于 -O0 的情况下给出相同的结果,所以这不应该是原因。

循环体中未使用变量 qt_category_enabled

将其用作宏似乎也不需要副作用,例如添加另一个级别的范围。

那么,为什么不只是

    #define qCDebug(category, ...) \
        if (category().isDebugEnabled()) \
            QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__)

1 个答案:

答案 0 :(得分:1)

看例子。

if (condition)
  qCDebug(...);
else
  exit(0);

如果使用 for 循环,则扩展代码的行为符合预期。

if (condition)
  for (...; category().isDebugEnabled(); ...)
    QMessageLogger(...);
else
  exit(0);

在if条件的情况下,else-branch总是附加到最近的if上,你会得到扩展代码

if (condition)
  if (category().isDebugEnabled())
    QMessageLogger(...);
  else
    exit(0);

看到区别了吗?

这个错误可以通过定义宏来修复

#define qCDebug(category, ...) \
  if (category().isDebugEnabled()) \
    QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__); \
  else (void)0

为什么不这样做,这是一个基于意见的问题。