# How to Use STATIC_REQUIRE for Compile-Time Assertions in Catch2

> Learn how to use STATIC_REQUIRE for compile-time assertions in Catch2. Enforce conditions at compile time and report successful checks in your test output.

- Repository: [Catch Org/Catch2](https://github.com/catchorg/Catch2)
- Tags: how-to-guide
- Published: 2026-07-29

---

**`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`](https://github.com/catchorg/Catch2/blob/main/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 to `false`; equivalent to `static_assert` with mandatory reporting.
- **`STATIC_REQUIRE_FALSE`** – Fails compilation if the condition evaluates to `true`; useful for asserting that certain conditions are impossible at compile time.
- **`STATIC_CHECK`** – Same as `STATIC_REQUIRE` but continues test execution after logging the failure (though compilation still fails).
- **`STATIC_CHECK_FALSE`** – Same as `STATIC_REQUIRE_FALSE` but with continuation semantics.

## How STATIC_REQUIRE Works Under the Hood

According to the Catch2 source code in [`src/catch2/catch_test_macros.hpp`](https://github.com/catchorg/Catch2/blob/main/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:

```cpp
#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:

1. **`static_assert`** – The standard C++ compile-time assertion that stops compilation when the condition evaluates to `false`, displaying the stringified condition as the error message.
2. **`SUCCEED`** – A macro defined in [`src/catch2/catch_message.hpp`](https://github.com/catchorg/Catch2/blob/main/src/catch2/catch_message.hpp) that 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`](https://github.com/catchorg/Catch2/blob/main/src/catch2/internal/catch_test_macro_impl.hpp), though most users interact only with the high-level macros in [`catch_test_macros.hpp`](https://github.com/catchorg/Catch2/blob/main/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.

```cpp
#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_REQUIRE`** combines `static_assert` with Catch2's `SUCCEED` macro to create compile-time assertions that appear in test reports.
- The macro is defined in **[`src/catch2/catch_test_macros.hpp`](https://github.com/catchorg/Catch2/blob/main/src/catch2/catch_test_macros.hpp)** and relies on **[`src/catch2/catch_message.hpp`](https://github.com/catchorg/Catch2/blob/main/src/catch2/catch_message.hpp)** for success reporting.
- Four variants exist: `STATIC_REQUIRE`, `STATIC_REQUIRE_FALSE`, `STATIC_CHECK`, and `STATIC_CHECK_FALSE`.
- Define **`CATCH_CONFIG_RUNTIME_STATIC_REQUIRE`** to 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`](https://github.com/catchorg/Catch2/blob/main/src/catch2/catch_test_macros.hpp)**. They depend on the **`SUCCEED`** macro from **[`src/catch2/catch_message.hpp`](https://github.com/catchorg/Catch2/blob/main/src/catch2/catch_message.hpp)**, and build upon internal implementation details found in **[`src/catch2/internal/catch_test_macro_impl.hpp`](https://github.com/catchorg/Catch2/blob/main/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.