Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHECK expression is hitting a static assert #621

Closed
rcdailey opened this issue Mar 23, 2016 · 10 comments
Closed

CHECK expression is hitting a static assert #621

rcdailey opened this issue Mar 23, 2016 · 10 comments

Comments

@rcdailey
Copy link

I have the following piece of code in a test case:

   auto mismatch_pair = std::mismatch(expected_result.begin(), expected_result.end(),
      DeliveryWidget::s_widgetNames.begin());

   CHECK(
      mismatch_pair.first == expected_result.end() &&
      mismatch_pair.second == DeliveryWidget::s_widgetNames.begin());

The errors I get:

error C2027: use of undefined type 'Catch::STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison'

I tried wrapping the two binary expressions utilizing == in parenthesis, this did not help. What am I supposed to do here? There is nothing in the documentation regarding this.

@refi64
Copy link

refi64 commented Mar 23, 2016

What about just separating them:

CHECK(mismatch_pair.first == expected_result.end());
CHECK(mismatch_pair.second == DeliveryWidget::s_widgetNames.begin());

It would have the same effect at run-time anyway. The expression is "too complex" because of the &&.

@ev-mp
Copy link

ev-mp commented Mar 23, 2016

Had the same issue in my code with:REQUIRE(  A ==B) && (C==D)) - reporting '..to complex'..Then additional parentheses and explicit '==true' condition worked for me :REQUIRE( true ==  ((A ==B) && (C==D)) )

On Wednesday, March 23, 2016 8:32 PM, Ryan Gonzalez <[email protected]> wrote:

What about just separating them:CHECK(mismatch_pair.first == expected_result.end());
CHECK(mismatch_pair.second == DeliveryWidget::s_widgetNames.begin());It would have the same effect at run-time anyway. The expression is "too complex" because of the &&.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub

@rcdailey
Copy link
Author

I'm fine doing that. I'd just like to learn more about why that expression won't work in one CHECK macro. There is nothing in the documentation to help me understand this.

@philsquared
Copy link
Collaborator

Good point. I should add something to the docs about that.
It is, indeed, the && (|| would have the same effect).
For && @kirbyfan64's approach seems best.
|| is a little trickier, but is seldom useful.

The reason for this limitation is that Catch decomposes the expression, then must reconstruct it so it can evaluate whether it was successful or not. While it is decomposed it can capture the values of the LHS and RHS of the expression for reporting purposes. If you introduce&& (or ||) into the expression it is no longer a simple, binary, expression. Splitting the expression up (@kirbyfan64's approach), or wrapping in parentheses (thereby losing the LHS/ RHS reporting capability) are the usual ways to deal with it.

@rcdailey
Copy link
Author

Maybe this could be solved with a new type of assertion macro (variable arguments):

CHECK_AND(a == b, c == d);
CHECK_OR(e != f, g != h, x == z);

Another thought is to create AND and OR macros, but those would conflict too easy and is probably not the best approach:

CHECK(a == b AND c == d);
CHECK(e != f OR g != h OR x == z);

Just some food for thought.

@refi64
Copy link

refi64 commented Mar 23, 2016

@rcdaily The problem with the first one is that it would be too easy to use accidentally:

CHECK(myfunc<int, int>() == 1); // Oops!

@tamboril
Copy link

Note you can always apply DeMorgan's Law to convert an OR to an AND so you can split it as mentioned above:

Instead of:
CHECK(a == 1 || b == 2),
do:
CHECK_FALSE(a != 1);
CHECK_FALSE(b != 2);

@mattfbacon
Copy link

@tamboril, this doesn't work. According to https://github.com/catchorg/Catch2/blob/devel/docs/assertions.md, the correct resolution is to put the expression in parentheses:

CHECK((a == 1 || b == 2));

@tamboril
Copy link

Thanks for the (belated) update!

@BeriPeric
Copy link

Thank you so much for this. I wrapped mine and it worked. I have literally spent hours on this stupid issue. I tried using the equal function to compare objects and it didn't work and then I tried using '==' didn't work. Then I tried '&&' didn't work. I even tried making my own method for equals with override, which didn't work and it hurt my brain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants