You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#defineCATCH_CONFIG_MAIN
#include<catch.hpp>TEST_CASE("foo")
{
uint32_t u = 0;
int32_t i = -1;
if (u > i) printf("foo\n"); // line 8REQUIRE(u > i); // line 9if (u > i) printf("foo\n"); // line 10
}
When compiled with -Wall (gcc) or -Wextra (clang), it reports warnings on line 8 and 10 but not 9. See https://godbolt.org/z/W9wQqy :
<source>:8:11: error: comparison of integer expressions of different signedness: 'uint32_t' {aka 'unsigned int'} and 'int32_t' {aka 'int'} [-Werror=sign-compare]
8 | if (u > i) printf("foo\n");
| ~~^~~
<source>:10:11: error: comparison of integer expressions of different signedness: 'uint32_t' {aka 'unsigned int'} and 'int32_t' {aka 'int'} [-Werror=sign-compare]
10 | if (u > i) printf("foo\n");
| ~~^~~
When you put parentheses around the expression, i.e., REQUIRE((u > i)), then gcc and clang report warning on that line too.
Right, that prevents Catch from decomposing and stringifying the expression...
Internally Catch suppresses warnings when evaluating the captured expression because of literals. In plain C++ code, this will not warn
size_t i = ...;
if (i < 2)
because the literal 2 can be easily converted into size_t without losing information. However, if you add extra indirection like Catch does, then that 2 is inferred to be an int. This means that without warning suppression, using REQUIRE(i < 2); in the above example would cause a warning about mismatched signedness in comparison.
This is obviously not ideal, so Catch2 uses a mitigation: it mentions the expression again in a context that will not be evaluated, like this: while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ), where __VA_ARGS__ is expression inside REQUIRE.
This works for MSVC, and used to work for Clang (but I had to go back to clang 3.4 for the warning to trigger), but apparently does not for current version of Clang or GCC.
Summary: I would like to have some way to force the compiler to check the code as written, without decomposition, but the suppression inside the actual evaluation is required for usability.
The old code caused warnings to fire under MSVC, and Clang <3.8.
I could not find a GCC version where it worked, but I assume that it
did at some point.
This new code causes all of MSVC, GCC, Clang, in current versions,
to emit signed/unsigned comparison warning in test like this:
```cpp
TEST_CASE() {
int32_t i = -1;
uint32_t j = 1;
REQUIRE(i != j);
}
```
Where previously only MSVC would emit the warning.
Fixes#1880
In the following code:
When compiled with
-Wall
(gcc) or-Wextra
(clang), it reports warnings on line 8 and 10 but not 9. See https://godbolt.org/z/W9wQqy :Looks like msvc reports warnings on all 3 lines, see https://godbolt.org/z/4uBsXT:
When you put parentheses around the expression, i.e.,
REQUIRE((u > i))
, then gcc and clang report warning on that line too.The text was updated successfully, but these errors were encountered: