If I run the following test witch 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));
}
I get the following output
/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
Why can Catch convert x and y to strings in the operator expression x == y but not in the function call expression eq(x, y)? Is it somehow possible to stringify the function call expression in a similar way to get output like this:
/path/to/MyTest.cpp:9: Failure:
CHECK(eq(x, y))
with expansion:
eq(1, 2)
I suspect once CHECK sees eq(x, y) it just sees the result of this function call as an expression.
You can insert a INFO before your CHECK to see the parameters to your function call:
INFO("x:" << x << ", y:" << y);
CHECK(eq(x, y));
which will be logged at the CHECK call (showing "with message"):
CHECK( eq(x, y) )
with expansion:
false
with message:
x:1, y:2
The interesting part is 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 &&.
where expr is x == y or eq(x, y).
How it works for x == y:
__catchResult <= expr results in __catchResult <= x == y which is equivalent to (__catchResult <= x) == y due to the lower precedence of <= compared to == (see C++ operator precedence). __catchResult <= x wraps x in an object with an == operator, which y gets passed to. That's how expr gets destructured. All the rest is easy to imagine.
Why it does not work for eq(x, y):
__catchResult <= expr results in __catchResult <= eq(x, y) and eq(x, y) is evaluated first (no destructuring).
For the same reason it does not work if the expression is surrounded by parentheses. For example, (x == y) would lead to __catchResult <= (x == y) in which case x == y is evaluated first (no destructuring). That's why CHECK((x == y)); causes output
/path/to/MyTest.cpp:8: Failure:
CHECK((x == y))
with expansion:
false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With