A lightweight, multi-expression assertion macro for C and C++, with optional debug-only usage.
A simple and powerful assertion macro that improves debug visibility with minimal code by allowing multiple conditions in a single statement — while keeping production builds fast and clean.
Standard assert() is a "fail-fast" gate: it stops at the first failure. If your logic requires three pointers and a state flag to be valid, standard assert only tells you about the first one that failed.
SMART_ASSERT() macro evaluates every condition passed to it before halting. This provides a complete "State Snapshot" of the failure, allowing you to see exactly which invariants were violated in a single crash report.
- Supports multiple conditions in one assert call
- Prints exactly which condition(s) failed
- Includes file, line, and function name
- Works in C99 and C++20 (or newer)
- Fully header-only, zero dependencies
- Compatible with both C and C++
- Offers optional debug-only behavior via
DEBUG_SMART_ASSERT(...)
Include the header:
#include "smart_assert.h"To enable debug-only assertions, define DEBUG_MODE before including the header:
#define DEBUG_MODE
#include "smart_assert.h"Evaluates one or more conditions and prints a detailed failure message for each failed condition.
Always enabled, regardless of build configuration.
SMART_ASSERT(x > 0, y == 5, is_valid());A wrapper macro for SMART_ASSERT(...) that is:
- Enabled only when
DEBUG_MODEis defined - Disabled otherwise — but still evaluates the expressions (side effects are preserved)
Example:
DEBUG_SMART_ASSERT(x++ < 10); // x++ still happens in release#define DEBUG_MODE
#include "smart_assert.h"
int main(void) {
int a = 1, b = 2, c = 0;
// This will print failures for b == 3 and c++ == 1
DEBUG_SMART_ASSERT(a == 1, b == 3, c++ == 1);
return 0;
}main.c:8: main: SMART_ASSERT(): Condition #2: `b == 3` failed.
main.c:8: main: SMART_ASSERT(): Condition #3: `c++ == 1` failed.
DEBUG_SMART_ASSERT(...)becomes:(void)(__VA_ARGS__); // All expressions are still evaluated
- No assertions, no messages, no aborts
- Useful for maintaining debug logic without performance cost in production
MASSERT correctly handles nested parentheses and braces but may be confused by commas inside string literals (e.g., MASSERT(s == "a,b")) as it does not implement a full C lexer.
- Copy
smart_assert.hto your project (e.g.include/folder) - Optionally define
DEBUG_MODEin debug builds - Use
SMART_ASSERT(...)for always-on checks - Use
DEBUG_SMART_ASSERT(...)for debug-only assertions
| Feature | Requirement |
|---|---|
| C Standard | C99 or newer (_Bool, _Static_assert, variadic macros) |
| C++ Standard | C++20 or newer (__VA_OPT__) |
| Compiler | GCC, Clang, or compatible |
MIT License © 2024 Georgios Evangelinos