diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 03f2f5780f..f326917d9d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -27,6 +27,7 @@ #include #include #include +#include // For NDEBUG compile time check #include #include #include @@ -58,10 +59,6 @@ #include -#if defined(NDEBUG) -# error "Dash Core cannot be compiled without assertions." -#endif - /** Maximum number of in-flight objects from a peer */ static constexpr int32_t MAX_PEER_OBJECT_IN_FLIGHT = 100; /** Maximum number of announced objects from a peer */ diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index fef9e86dcd..a711cba012 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/src/util/check.h b/src/util/check.h index d18887ae95..75aefe4483 100644 --- a/src/util/check.h +++ b/src/util/check.h @@ -21,7 +21,7 @@ class NonFatalCheckError : public std::runtime_error * - where the condition is assumed to be true, not for error handling or validating user input * - where a failure to fulfill the condition is recoverable and does not abort the program * - * For example in RPC code, where it is undersirable to crash the whole program, this can be generally used to replace + * For example in RPC code, where it is undesirable to crash the whole program, this can be generally used to replace * asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC * caller, which can then report the issue to the developers. */ @@ -38,4 +38,18 @@ class NonFatalCheckError : public std::runtime_error } \ } while (false) +#if defined(NDEBUG) +#error "Cannot compile without assertions!" +#endif + +/** Helper for Assert(). TODO remove in C++14 and replace `decltype(get_pure_r_value(val))` with `T` (templated lambda) */ +template +T get_pure_r_value(T&& val) +{ + return std::forward(val); +} + +/** Identity function. Abort if the value compares equal to zero */ +#define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }() + #endif // BITCOIN_UTIL_CHECK_H diff --git a/src/validation.cpp b/src/validation.cpp index b3bf169b53..8ae5ab6101 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -38,6 +38,7 @@ #include #include #include +#include // For NDEBUG compile time check #include #include #include @@ -62,10 +63,6 @@ #include #include // Required for boost::this_thread::interruption_point(); -#if defined(NDEBUG) -# error "Dash Core cannot be compiled without assertions." -#endif - #define MICRO 0.000001 #define MILLI 0.001 diff --git a/test/lint/lint-assertions.sh b/test/lint/lint-assertions.sh index a4c6f0a8d4..1edff2b9ac 100755 --- a/test/lint/lint-assertions.sh +++ b/test/lint/lint-assertions.sh @@ -23,7 +23,7 @@ fi # Macro CHECK_NONFATAL(condition) should be used instead of assert for RPC code, where it # is undesirable to crash the whole program. See: src/util/check.h # src/rpc/server.cpp is excluded from this check since it's mostly meta-code. -OUTPUT=$(git grep -nE 'assert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp") +OUTPUT=$(git grep -nE '\<(A|a)ssert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp") if [[ ${OUTPUT} != "" ]]; then echo "CHECK_NONFATAL(condition) should be used instead of assert for RPC code." echo