MRDOCS_ASSERT
Assert that a condition holds.
Synopsis
Declared in <mrdocs/Support/Error/Assert.hpp>
#define MRDOCS_ASSERT(x)
Description
Use it as a statement, with a trailing semicolon, to check a precondition or invariant:
namespace mrdocs {
int
elementAt(std::vector<int> const& v, std::size_t i)
{
MRDOCS_ASSERT(i < v.size());
return v[i];
}
} // mrdocs
In debug builds, the assertion roughly expands to:
// MRDOCS_ASSERT(i < v.size());
// The condition is evaluated once. If it's false,
// assert_failed prints "assertion failed: i < v.size()
// on line N in <file>" to stderr, and then the program
// traps (__builtin_trap on GCC/Clang, __debugbreak on
// MSVC).
static_cast<void>(!!(i < v.size()) ||
(assert_failed("i < v.size()",
__builtin_FILE(), __builtin_LINE()),
static_cast<void>(__builtin_trap(),
__builtin_unreachable()),
true));
In release builds (NDEBUG), it expands to:
// MRDOCS_ASSERT(i < v.size());
// The condition is dropped by the preprocessor. It's
// never compiled or evaluated.
static_cast<void>(false);
Some consequences of this definition:
-
The condition must not have side effects the program depends on, such as
MRDOCS_ASSERT(queue.pop()), since release builds never run it. Variables used only inside assertions can trigger unused‐variable warnings there. -
The expansion calls
assert_failedunqualified, so in debug builds the macro only compiles wheremrdocs::assert_failedis found by lookup: insidenamespace mrdocs, or afterusing namespace mrdocs;. -
It's a
voidexpression, not a full statement, so a trailing semicolon is needed. -
It's a single‐argument macro. Wrap a condition that has a top‐level comma in parentheses, as in
MRDOCS_ASSERTstd::is_same_v[].
When to use it:
-
Preconditions of a function, such as a non‐null pointer from Clang (
MRDOCS_ASSERT(D)) or an index in range. -
Invariants of a type, such as
has_value()in an accessor,!valueless_after_move()on aPolymorphic, ort‐>Kind == T::kind_idbefore a cast to the derived type. -
Assumptions a later line depends on, such as a container being non‐empty before
front().
Use it when there's a condition you can state, so a debug build prints it when it fails. When there's no condition and the location itself is the bug, such as the default: of a switch that handles every enumerator, use MRDOCS_UNREACHABLE instead. Neither macro is for input a user can control, since release builds don't check it: return an error with MRDOCS_CHECK or MRDOCS_CHECK_OR there.
See Also
Created with MrDocs