FAILED: REQUIRE( a == N ) with expansion: 100000 (0x186a0) == 100000 (0x186a0)
Took me a bit to understand what is even going on here. Looking at the Catch2 source, I can see it evaluates the value under test (__VA_ARGS__) twice. Which in a multi-threaded environment leads to this awesome message in the title.
P. S. I'm using the latest v2 release, not v3 (I really wish you could keep offering the header-only option, perhaps with reduced features if necessary).
Technically it doesn't evaluate it twice (you can check this by using an expression with side effects), but evaluation and stringification are separate steps. REQUIRE captures the operands in the expression by reference, so if a different thread modifies it after the expression is evaluated 🤷
As to the second part, what advantage do you see in having a header-only option over the amalgamated files?
I see! If you think it's not a bug that's fair enough, I just wanted to point it out for discussion. I don't see a way to testing multi-threading without actually running it. But for tests like this it shouldn't matter what the faulting value is, in all honesty.
There is no simpler way to deploy a third-party dependency than to simply #include <> the header file(s), which can be included in the parent repo directly, cloned from Github etc. I know, of course, some of the modern way to deploy complex dependencies that need compilation, but most of my projects don't need any and don't use CMake. Catch2 was superbly easy to use (including all my other dependencies which are header-only), and since v3 requires compilation I would need to come up with an entirely new way of deploying it, like using VCPKG. Not saying I can't, but it's a step back in ease of use.
Thank you for listening!
You shouldn't be interacting with Catch2 from multiple threads at all. When testing multi-threaded code, you need specialized approaches, because the generic one, tossing in a critical section around interactions with outside code, hides a lot of problem due to imposing an implicit thread ordering and serialized execution.
As for the second, I understand that avoiding separate compilation can simplify the distribution in some cases, but I still don't see how using extras/catch_amalgamated.hpp and extras/catch_amalgamated.cpp is meaningfully worse than the single header in v2.
That's a very good point, thank you. Indeed, the last things I would want is for the assertion macros to have an internal mutex, but I also didn't realize they are not thread-safe. In my particular case there was no race on the test macros, only on the atomic value being tested, but it's good to know.
As soon as there is a .cpp file, you're facing a problem of what to do with it. It's not a big problem, but you need to do something about it. I'm sure you have valid reasons for the change, and it's not for me to tell you how you should maintain your own open source project that I've enjoyed for years. I just think I'll stick to v2 at least in some of my projects, or maybe someone will make a fork of v2 with further development.