The Assert
/Assume
macros are implemented via lambda functions to allow the result of the assertion to both be evaluated (and trigger an abort) and be returned without having the expression be evaluated twice.
This causes some ugly namespacing issues though. Because there’s a function call, clang’s thread safety annotations don’t get passed through (as the lambda is unannotated), possibly causing an unnecessary compiler error because the compiler loses track that a mutex is held when a guarded variable is accessed.
It also seems that gcc (but not clang) gets confused about member functions (but not member variables), eg:
0class TestAssert
1{
2public:
3 int variable = 3;
4 int test_1(void) { return variable; }
5 int test_2(void) {
6 auto x = [&]() {
7 Assert(test_1() == 3);
8 };
9 x();
10 return ++variable;
11 }
12};
results in:
0test/util_tests.cpp:91:26: error: cannot call member function ‘int util_tests::TestAssert::test_1()’ without object
1 91 | Assert(test_1() == 3);
requiring you to write Assert(this->test_1() == 3)
instead.