2017-03-15 50 views
3

如果我运行下面的测试女巫Catch字符串皈依

bool eq(int x, int y) { 
    return x == y; 
} 

TEST_CASE("operator vs. function call") { 
    int x = 1; 
    int y = 2; 
    CHECK(x == y); 
    CHECK(eq(x, y)); 
} 

我得到以下输出

/path/to/MyTest.cpp:8: Failure: 
    CHECK(x == y) 
with expansion: 
    1 == 2 

/path/to/MyTest.cpp:9: Failure: 
    CHECK(eq(x, y)) 
with expansion: 
    false 

为什么能赶上转换xy到字符串运算符表达式x == y但不在函数调用表达式eq(x, y)中?是它在某种程度上可能字符串化以类似的方式函数调用表达式得到的输出是这样的:

/path/to/MyTest.cpp:9: Failure: 
    CHECK(eq(x, y)) 
with expansion: 
    eq(1, 2) 

回答

1

有趣的部分是this

#define INTERNAL_CATCH_TEST(expr, resultDisposition, macroName) \ 
    do { \ 
     Catch::ResultBuilder __catchResult(macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition); \ 
     try { \ 
      CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ 
      (__catchResult <= expr).endExpression(); \ 
      CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ 
     } \ 
     catch(...) { \ 
      __catchResult.useActiveException(resultDisposition); \ 
     } \ 
     INTERNAL_CATCH_REACT(__catchResult) \ 
    } while(Catch::isTrue(false && static_cast<bool>(!!(expr)))) // expr here is never evaluated at runtime but it forces the compiler to give it a look 
    // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. 

其中exprx == yeq(x, y)

它是如何工作的x == y:由于与==<=较低的优先级(见C++ operator precedence
__catchResult <= expr结果__catchResult <= x == y这相当于(__catchResult <= x) == y__catchResult <= xx包含在==运算符的对象中,该运算符将y传递给对象。这就是expr得到解构。其余的很容易想象。

为什么它不为eq(x, y)工作:

__catchResult <= expr导致__catchResult <= eq(x, y)eq(x, y)首先计算(不拆解)。

出于同样的原因,如果表达式由圆括号包围,则它不起作用。例如,(x == y)将导致__catchResult <= (x == y)在这种情况下首先评估x == y(不解构)。这就是为什么CHECK((x == y));导致输出

/path/to/MyTest.cpp:8: Failure: 
    CHECK((x == y)) 
with expansion: 
    false 
2

我怀疑曾经CHECK看到eq(x, y)它只是看到这个函数调用作为一个表达式的结果。

您可以将您的CHECKINFO看参数,以你的函数调用:

INFO("x:" << x << ", y:" << y); 
CHECK(eq(x, y)); 

将在CHECK通话记录(显示“有消息”):

CHECK(eq(x, y)) 
with expansion: 
    false 
with message: 
    x:1, y:2