How to Use STATIC_REQUIRE for Compile-Time Assertions in Catch2
STATIC_REQUIRE is a Catch2 macro that wraps static_assert to enforce compile-time conditions while reporting successful checks in your test output.
When writing C++ tests with the Catch2 framework, you often need to validate type traits, sizes, or other conditions that can be evaluated at compile time. The STATIC_REQUIRE macro, defined in src/catch2/catch_test_macros.hpp, provides a seamless way to perform these compile-time assertions that integrate with Catch2's test reporting system.
Understanding STATIC_REQUIRE and Related Macros
STATIC_REQUIRE and its companions—STATIC_REQUIRE_FALSE, STATIC_CHECK, and STATIC_CHECK_FALSE—are the compile-time counterparts to Catch2's runtime assertion macros (REQUIRE and CHECK). While REQUIRE halts execution when a runtime condition fails, STATIC_REQUIRE triggers a compilation error when a compile-time condition is false.
These macros serve distinct purposes in your test suite:
STATIC_REQUIRE– Fails compilation if the condition evaluates tofalse; equivalent tostatic_assertwith mandatory reporting.STATIC_REQUIRE_FALSE– Fails compilation if the condition evaluates totrue; useful for asserting that certain conditions are impossible at compile time.STATIC_CHECK– Same asSTATIC_REQUIREbut continues test execution after logging the failure (though compilation still fails).STATIC_CHECK_FALSE– Same asSTATIC_REQUIRE_FALSEbut with continuation semantics.
How STATIC_REQUIRE Works Under the Hood
According to the Catch2 source code in src/catch2/catch_test_macros.hpp, when the runtime-only configuration is not enabled, STATIC_REQUIRE expands to a standard C++ static_assert followed by a SUCCEED call:
#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( #__VA_ARGS__ )
This implementation relies on two key components:
static_assert– The standard C++ compile-time assertion that stops compilation when the condition evaluates tofalse, displaying the stringified condition as the error message.SUCCEED– A macro defined insrc/catch2/catch_message.hppthat records a successful assertion in the test report. This ensures that passing static checks appear in your test output, maintaining visibility into which compile-time validations were executed.
The macro hierarchy builds upon lower-level internal implementations found in src/catch2/internal/catch_test_macro_impl.hpp, though most users interact only with the high-level macros in catch_test_macros.hpp.
Runtime Fallback Configuration
If you define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE before including Catch2, these macros forward to their runtime equivalents (REQUIRE, REQUIRE_FALSE, etc.) instead of invoking static_assert. This allows you to switch between compile-time and runtime validation without modifying your test code, useful for debugging or platform-specific testing scenarios.
Practical Examples of Compile-Time Assertions
Use STATIC_REQUIRE within your TEST_CASE blocks to validate template metaprogramming, type traits, or constexpr computations. Because the assertion runs at compile time, you cannot use runtime variables in the condition.
#include <catch2/catch_test_macros.hpp>
#include <type_traits>
#include <limits>
TEST_CASE( "Compile-time type validation" ) {
// Verify int is exactly 4 bytes
STATIC_REQUIRE( sizeof(int) == 4 );
// Ensure char is unsigned on this platform
STATIC_REQUIRE_FALSE( std::is_signed<char>::value );
// Validate numeric limits at compile time
STATIC_CHECK( std::numeric_limits<int>::max() > 1000 );
}
TEST_CASE( "Template compile-time checks" ) {
// Verify a type trait for a specific template instantiation
STATIC_REQUIRE( std::is_trivially_copyable_v<int> );
STATIC_REQUIRE_FALSE( std::is_pointer_v<double> );
}
When a condition evaluates to true, the code compiles and the test reports a successful assertion. When a condition evaluates to false, compilation halts with the static_assert error message, preventing the generation of an invalid test binary.
Summary
STATIC_REQUIREcombinesstatic_assertwith Catch2'sSUCCEEDmacro to create compile-time assertions that appear in test reports.- The macro is defined in
src/catch2/catch_test_macros.hppand relies onsrc/catch2/catch_message.hppfor success reporting. - Four variants exist:
STATIC_REQUIRE,STATIC_REQUIRE_FALSE,STATIC_CHECK, andSTATIC_CHECK_FALSE. - Define
CATCH_CONFIG_RUNTIME_STATIC_REQUIREto convert these macros to runtime assertions without changing test code. - Failed assertions prevent compilation, while successful assertions are logged as passed tests.
Frequently Asked Questions
What is the difference between STATIC_REQUIRE and standard static_assert?
STATIC_REQUIRE wraps static_assert and adds a call to SUCCEED, which registers the passing assertion in Catch2's test output. Standard static_assert only stops compilation on failure without providing feedback in your test logs when the assertion passes.
Can I disable compile-time checking and run STATIC_REQUIRE assertions at runtime?
Yes. By defining CATCH_CONFIG_RUNTIME_STATIC_REQUIRE before including Catch2 headers, the STATIC_REQUIRE macros expand to their runtime equivalents (REQUIRE, CHECK). This allows you to debug test logic or work around compiler-specific issues without rewriting your test cases.
Where are the STATIC_REQUIRE macros defined in the Catch2 source code?
The macros are defined in src/catch2/catch_test_macros.hpp. They depend on the SUCCEED macro from src/catch2/catch_message.hpp, and build upon internal implementation details found in src/catch2/internal/catch_test_macro_impl.hpp.
Why would I use STATIC_REQUIRE_FALSE instead of negating the condition in STATIC_REQUIRE?
STATIC_REQUIRE_FALSE provides clearer intent and better error messages when asserting that a condition should not be true. It automatically wraps the condition in negation and formats the error message to indicate the expectation of falsity, making compile-time failures easier to diagnose.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →