MRDOCS_ASSERT

Assert that a condition holds.

Synopsis

#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_failed unqualified, so in debug builds the macro only compiles where mrdocs::assert_failed is found by lookup: inside namespace mrdocs, or after using namespace mrdocs;.

  • It's a void expression, 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 a Polymorphic, or t‐>Kind == T::kind_id before 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.

Parameters

Name

Description

x

The condition to check.

See Also

Created with MrDocs