【问题标题】:Is the if - else redundant in this macro?if - else 在这个宏中是多余的吗?
【发布时间】:2015-02-28 05:05:46
【问题描述】:

这是对这个问题的跟进:

What's the use of do while(0) when we define a macro?

此宏用于 Qt 单元测试:

#define QVERIFY2(statement, description) \
do {\
    if (statement) {\
        if (!QTest::qVerify(true, #statement, (description), __FILE__, __LINE__))\
            return;\
    } else {\
        if (!QTest::qVerify(false, #statement, (description), __FILE__, __LINE__))\
            return;\
    }\
} while (0)

它验证语句,如果它是假的,它会产生一条带有给定描述的错误消息。

我的问题是,if - else 内部声明的原因是什么?为什么不这么简单定义呢?

#define QVERIFY2(statement, description) \
do {\
    if (!QTest::qVerify(statement, #statement, (description), __FILE__, __LINE__))\
        return;\
    }\
} while (0)

我怀疑解释与所提到的问题相同。有什么想法吗?

更新

为了提供更多上下文,还定义了以下宏的变体,没有描述:

#define QVERIFY(statement) \
do {\
    if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\
        return;\
} while (0)

这表明该技巧与description 参数有关。

【问题讨论】:

  • 仅根据您发布的内容,较短的版本应该和较长的版本一样有效。
  • 可能是为了提高清晰度。这样我们就知道statement是一个布尔值(if(statement)),否则我们不能确定qVerify(statement..,不看qVerify定义
  • 宏所做的一件事是确保在 description 之前评估 statement
  • @rici 它还确保description 被评估,无论分支采用哪种方式。
  • @1nflktd,我也是这么想的,但本来可以这样做if (!QTest::qVerify((statement) != 0, ...

标签: c++ qt


【解决方案1】:

一种可能的解释是宏确保statementdescription 之前被评估。

【讨论】:

  • 这确实是两者的唯一区别。
  • 现在如果我想一想,statement 不会在description 之前被评估吗?还是函数参数的求值顺序未定义?
  • @GáborAngyal 我相信正确的术语是未指定。它基本上留给编译器编写者按照他们认为最简单或最快的顺序来完成。
【解决方案2】:

一个重要的区别是,如果QTest::qVerify 的第一个参数的类型为bool,则可在上下文中转换bool 的类型比可隐式转换bool

给定

struct S { explicit operator bool(); } s;
void f(bool);

调用f(s)无效,但if (s) f(true); else f(false);有效。

但是,鉴于您在问题中显示的定义 QVERIFY 宏,这似乎从未真正考虑过。

【讨论】:

  • 这也是一个很好的答案,但我认为另一个是一个更有力的论点。
猜你喜欢
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多