Catch2: Boolean "or" not possible in REQUIRE

Created on 13 Dec 2018  Â·  8Comments  Â·  Source: catchorg/Catch2

Description

I can not use a boolean or (without an extra parenthesis) in REQUIRE.

Steps to

in any TEST_CASE, put a

 REQUIRE ((true) || (false));

Extra information

Solution:
put an extra parenthesis around the operation (which should not be nessecary, IMHO):

 REQUIRE (((true) || (false)));

Compiler message:

[maximilian@localhost ZENeural]$ make test
make -C ./library/tests  #make the unit tests
make[1]: Entering directory '/home/maximilian/Dokumente/CODING/NN/ZENeural/library/tests'
g++ -lpthread -O0 --std=c++17 test_main.cpp -g -o test -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
In file included from test_main.cpp:18:0:
test_GatedNeuron.hpp: In function ‘void ____C_A_T_C_H____T_E_S_T____18()’:
test_GatedNeuron.hpp:21:29: error: no match for ‘operator||’ (operand types are ‘Catch::ExprLhs<bool>’ and ‘bool’)
             REQUIRE ((true) || (false));
                             ^
test_GatedNeuron.hpp:21:29: note: candidate: operator||(bool, bool) <built-in>
test_GatedNeuron.hpp:21:29: note:   no known conversion for argument 1 from ‘Catch::ExprLhs<bool>’ to ‘bool’
make[1]: *** [makefile:10: all] Error 1
make[1]: Leaving directory '/home/maximilian/Dokumente/CODING/NN/ZENeural/library/tests'
make: *** [makefile:32: test] Error 2
[maximilian@localhost ZENeural]$
  • Catch version: Catch v2.3.0 Generated: 2018-07-23 10:09:14.936841
  • Operating System: Linux
  • Compiler+version: Gcc 7
Working as intended

Most helpful comment

We could in that very specific case. It wouldn't add a lot of extra complexity.
But then what about the next case ... and the next. It's not a general solution. I think your case is fairly rare, and there's an easy workaround, so I don't think it justifies special-casing it.
I could be persuaded otherwise if it turns out it's not such a rare case, though.

Not supporting logical AND makes sense because you can use multiple CHECK and REQUIRE statements. If one these statements fail, the error message will be shorter and just from the line number you can tell which test failed. A logical OR cannot be replaced this way.

I specifically searched for this issue here because I hit on this problem when implementing a state machine.

All 8 comments

This is by design. All supported operators add extra complexity to the (heavily templated) mechanism for decomposing expressions, so only the comparison and relational operators are supported.

couldn't you just overload the operator on that class the boolean expression is put into?

We could in that very specific case. It wouldn't add a lot of extra complexity.
But then what about the next case ... and the next. It's not a general solution. I think your case is fairly rare, and there's an easy workaround, so I don't think it justifies special-casing it.
I could be persuaded otherwise if it turns out it's not such a rare case, though.

I wouldn't say that it's rare. You check wether something is a OR b. Lets say I have a state machine that can only have two states (or three or n). With a simple || I could check wether the state of the state machine is still valid.

We could in that very specific case. It wouldn't add a lot of extra complexity.
But then what about the next case ... and the next. It's not a general solution. I think your case is fairly rare, and there's an easy workaround, so I don't think it justifies special-casing it.
I could be persuaded otherwise if it turns out it's not such a rare case, though.

Not supporting logical AND makes sense because you can use multiple CHECK and REQUIRE statements. If one these statements fail, the error message will be shorter and just from the line number you can tell which test failed. A logical OR cannot be replaced this way.

I specifically searched for this issue here because I hit on this problem when implementing a state machine.

you could combine the Catch2 tag [!shouldfail] and De Morgan's Law as a workaround
using - symbol as a logical NOT

A OR B -> -(-A AND -B)

Create a the following testcase

TEST_CASE("mytest", "[!shouldfail]") {
  REQUIRE(!A);
  REQUIRE(!B);
}

That's... not an ideal workaround, but not supporting || and && in assertions is a hardline that will not change, unless the language fundamentally changes and it becomes possible to implement user-defined logical operators with short-circuiting.

As the language is now, if (missiles_detected() && !launch_countermissiles()) { panic(); } will not launch missiles unless other missiles are detected, but REQUIRE(missiles_detected() && !launch_countermissiles()); would always launch the missiles.

This is a good reason not to overload logical operators.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Viatorus picture Viatorus  Â·  3Comments

emil-e picture emil-e  Â·  8Comments

RT222 picture RT222  Â·  4Comments

zwcloud picture zwcloud  Â·  5Comments

arnavb picture arnavb  Â·  7Comments