Libassert
The most over-engineered C++ assertion library
Install / Use
/learn @jeremy-rifkin/LibassertREADME
libassert <!-- omit in toc -->
<!-- <br/> [](https://godbolt.org/z/Eonafvxof) --> <p align="center">The most over-engineered C++ assertion library</p>Table of Contents: <!-- omit in toc -->
- 30-Second Overview
- Philosophy
- Features
- Methodology
- Considerations
- In-Depth Library Documentation
- Integration with Test Libraries
- ABI Versioning
- Usage
- Platform Logistics
- Replacing <cassert>
- FAQ
- Cool projects using libassert
- Comparison With Other Languages
30-Second Overview
Library philosophy: Provide as much helpful diagnostic info as possible.
Some of the awesome things the library does:
#include <libassert/assert.hpp>
void zoog(const std::map<std::string, int>& map) {
DEBUG_ASSERT(map.contains("foo"), "expected key not found", map);
}

ASSERT(vec.size() > min_items(), "vector doesn't have enough items", vec);

std::optional<float> get_param();
float f = *ASSERT_VAL(get_param());

Types of assertions:
Conditional assertions:
DEBUG_ASSERT: Checked in debug but does nothing in release (analogous to the standard library'sassert)ASSERT: Checked in both debug and releaseASSUME: Checked in debug and serves as an optimization hint in release
Unconditional assertions:
PANIC: Triggers in both debug and releaseUNREACHABLE: Triggers in debug, marked as unreachable in release
Prefer lowecase assert?
You can enable the lowercase debug_assert and assert aliases with -DLIBASSERT_LOWERCASE.
Summary of features:
- Automatic decomposition of assertion expressions without macros such as
ASSERT_EQetc. - Assertion messages
- Arbitrary extra diagnostics
- Syntax highlighting
- Stack traces
DEBUG_ASSERT_VALandASSERT_VALvariants that return a value so they can be integrated seamlessly into code, e.g.FILE* f = ASSERT_VAL(fopen(path, "r") != nullptr)- Smart literal formatting
- Stringification of user-defined types
- Custom failure handlers
- Catch2/Gtest integrations
- {fmt} support
- Programatic breakpoints on assertion failures for more debugger-friendly assertions, more info below
CMake FetchContent Usage
include(FetchContent)
FetchContent_Declare(
libassert
GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert.git
GIT_TAG v2.2.1 # <HASH or TAG>
)
FetchContent_MakeAvailable(libassert)
target_link_libraries(your_target libassert::assert)
# On windows copy libassert.dll to the same directory as the executable for your_target
if(WIN32)
add_custom_command(
TARGET your_target POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:libassert::assert>
$<TARGET_FILE_DIR:your_target>
)
endif()
Be sure to configure with -DCMAKE_BUILD_TYPE=Debug or -DDCMAKE_BUILD_TYPE=RelWithDebInfo for symbols and line
information.
On macOS it is recommended to generate a .dSYM file, see Platform Logistics below.
For other ways to use the library, such as through package managers or a system-wide installation, see Usage below.
Philosophy
Fundamentally the role of assertions is to verify assumptions made in software and identify violations close to their sources. Assertion tooling should prioritize providing as much information and context to the developer as possible to allow for speedy triage. Unfortunately, existing language and library tooling provides very limited triage information.
For example with stdlib assertions an assertion such as assert(n <= 12); provides no information upon failure about
why it failed or what led to its failure. Providing a stack trace and the value of n greatly improves triage and
debugging. Ideally an assertion failure should provide enough diagnostic information that the programmmer doesn't have
to rerun in a debugger to pinpoint the problem.
Version 1 of this library was an exploration looking at how much helpful information and functionality could be packed into assertions while also providing a quick and easy interface for the developer.
Version 2 of this library takes lessons learned from version 1 to create a tool that I personally have found indispensable in development.
Features
Automatic Expression Decomposition <!-- omit in toc -->
The most important feature this library supports is automatic expression decomposition. No need for ASSERT_LT or other
such hassle, assert(vec.size() > 10); is automatically understood, as showcased above.
Expression Diagnostics <!-- omit in toc -->
Values involved in assert expressions are displayed. Redundant diagnostics like 2 => 2 are avoided.
DEBUG_ASSERT(map.count(1) == 2);

Only the full assert expression is able to be extracted from a macro call. Showing which parts of the expression correspond to what values requires some basic expression parsing. C++ grammar is ambiguous but most expressions can be disambiguated.
Extra Diagnostics <!-- omit in toc -->
All assertions in this library support optional diagnostic messages as well as arbitrary other diagnostic messages.
FILE* f = ASSERT_VAL(fopen(path, "r") != nullptr, "Internal error with foobars", errno, path);
Special handling is provided for errno, and strerror is automatically called.
Note: Extra diagnostics are only evaluated in the failure path of an assertion.

Stack Traces <!-- omit in toc -->
A lot of work has been put into generating pretty stack traces and formatting them as nicely as possible. Cpptrace is used as a portable and self-contained solution for stacktraces pre-C++23. Optional configurations can be found in the library's documentation.
One feature worth noting is that instead of always printing full paths, only the minimum number of directories needed to differentiate paths are printed.

Another feature worth pointing out is that the stack traces will fold traces with deep recursion:

Syntax Highlighting <!-- omit in toc -->
The assertion handler applies syntax highlighting wherever appropriate, as seen in all the screenshots above. This is to help enhance readability.
Diff Highlighting <!-- omit in toc -->
Libassert can provide diff highlighting on output:

This is opt-in with libassert::set_diff_highlighting(true);
Custom Failure Handlers <!-- omit in toc -->
Libassert supports custom assertion failure handlers:
void handler(const assertion_info& info) {
throw std::runtime_error("Assertion failed:\n" + assertion.to_string());
}
int main() {
libassert::set_failure_handler(handler);
}
More details below.
Debug Stringification <!-- omit in toc -->
A lot of care is given to producing debug stringifications of values as effectively as possible: Strings, characters, numbers, should all be printed as you'd expect. Additionally containers, tuples, std::optional, smart pointers, etc. are all stringified to show as much information as possible. If a us
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
