Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

assert return-value, but run either way

Typically, when I erase an element from a set, I want to assert that it was actually erased: ie

assert(s.erase(e));

but then the element doesn't get erased when NDEBUG is set. But if I write

bool removed = s.erase(e);
assert(removed);

the compiler complains that 'removed' is unused when NDEBUG is set.

How can I do this right?


I ended up just creating a utility method:

inline void run_and_assert(bool b) {
    assert(b);
}

now I can say

run_and_assert(s.erase(e));

Are there any drawbacks to this? It seems simpler to me than luiscubal's solution

like image 976
dspyz Avatar asked Dec 17 '13 20:12

dspyz


1 Answers

The first example is wrong because the assert expression will be removed when NDEBUG is defined, so s.erase(e) won't be called at all.

The argument of assert should NEVER have side-effects.

The second approach is better, though the warning might indeed be annoying, but there are ways to silence the warning.

Alternatively you could come up with your own assert statement that always executes the code.

#ifdef NDEBUG
#define assert_always_execute(x) (x)
#else
#define assert_always_execute(x) assert(x)
#endif
like image 73
luiscubal Avatar answered Sep 22 '22 09:09

luiscubal