Reputation: 6190
I've noticed that some code often looks like this:
#ifdef DEBUG
assert(i == 1);
#endif //DEBUG
and that you may have several blocks of these sitting around in your raw code. Having to write out each block is tedious and messy.
Would it be plausible to have a function like this:
auto debug_assert = [](auto expr) {
#ifdef DEBUG
assert(expr);
#endif //DEBUG
};
or something like this:
#ifdef DEBUG
auto debug_assert = [](bool expr) {
assert(expr);
};
#else //DEBUG
void debug_assert(bool expr) {}
#endif //DEBUG
to get a zero-cost assert when the DEBUG flag is not specified? (i.e. it should have the same effect as if it was not put into the code without the lambda running, etc. and be optimized out by the g++/clang compilers).
Upvotes: 0
Views: 278
Reputation: 15814
As mentioned by @KerrekSB, you can already disable asserts by defining NDEBUG
before including <cassert>
. The best way to ensure that it's defined before including the header file is to list it in as the argument to the compiler (with gcc it's -DNDEBUG
)
Note: the assert
is removed by replacing it with a no-op expression, and there, the argument isn't evaluated at all (which is different from your suggested solution)! This is why it's of utmost importance to not call any functions that have side effects in assert
.
For completeness: here is how assert
can be implemented:
#include <cstdio>
#include <cstdlib>
#ifndef NDEBUG
#define assert(EXPRESSION) ((EXPRESSION) ? (void)0 : (printf("assertion failed at line %d, file %s: %s\n", __LINE__, __FILE__, #EXPRESSION), exit(-1)))
#else
#define assert(EXPRESSION) (void)0
#endif
Introducing your own assert
-style macro is very commonly done. There are quite a lot of reasons you may want to do this:
REQUIRE
and how they use expression templates to decompose the expression into individual elements and stringify them)exit()
ing the program, like throwing an exception, mailing the developer, logging to a file, breaking into the debuggerUpvotes: 6