# How to Disable Exceptions in fmtlib: Complete Configuration Guide

> Learn how to disable exceptions in fmtlib by setting FMT_USE_EXCEPTIONS to 0. This guide shows you how to remove try catch blocks and redirect error handling.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: how-to-guide
- Published: 2026-09-12

---

**Set the compile-time macro `FMT_USE_EXCEPTIONS` to `0` to disable C++ exceptions in fmtlib, which strips out all internal `try/catch` blocks and redirects error handling to `fmt::assert_fail`.**

Disabling exceptions in {fmt} is critical for embedded systems, real-time applications, and environments compiled with `-fno-exceptions`. The library provides robust exception-free operation through the `FMT_USE_EXCEPTIONS` configuration macro, which is evaluated in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) before any formatting logic is compiled.

## Understanding the FMT_USE_EXCEPTIONS Macro

The {fmt} library controls exception support through the **`FMT_USE_EXCEPTIONS`** macro defined in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) (lines 46–57). When this macro evaluates to `0`, the library eliminates exception overhead by redefining exception handling constructs as no-ops.

```cpp
// include/fmt/core.h – exception control macros (lines 46-57)
#if FMT_USE_EXCEPTIONS

#  define FMT_TRY   try

#  define FMT_CATCH(x) catch (x)

#else

#  define FMT_TRY   if (true)          // no try block generated

#  define FMT_CATCH(x) if (false)     // no catch block generated

#endif

```

When `FMT_USE_EXCEPTIONS` is `0`, the library automatically translates all `throw fmt::format_error` statements into calls to **`fmt::assert_fail`**, which aborts the program by default. The macro is automatically detected if you compile with `-fno-exceptions` on GCC/Clang or with `_HAS_EXCEPTIONS==0` on MSVC, but you can also override it manually.

## Methods to Disable Exceptions in fmtlib

You can disable exceptions through three primary configuration methods, depending on your build system and integration approach.

### CMake Configuration

When building {fmt} as a compiled library, pass the CMake option to disable exception handling at the configuration stage:

```bash
cmake -DFMT_USE_EXCEPTIONS=OFF ..

# or explicitly set to 0

cmake -DFMT_USE_EXCEPTIONS=0 ..

```

This definition propagates through the build system defined in [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt) and sets the preprocessor macro consistently across all translation units.

### Compiler Flags

Define the macro via compiler flags when building your project. This method works for both header-only and compiled library usage:

```bash

# GCC/Clang

g++ -std=c++20 -DFMT_USE_EXCEPTIONS=0 -I/path/to/fmt/include main.cpp -lfmt

# MSVC

cl /std:c++20 /DFMT_USE_EXCEPTIONS=0 /I\path\to\fmt\include main.cpp fmt.lib

```

### Source-Level Macro Definition

Define `FMT_USE_EXCEPTIONS` before including any {fmt} headers. This approach is necessary when using **header-only mode** (`FMT_HEADER_ONLY`):

```cpp
#define FMT_USE_EXCEPTIONS 0          // Must precede all fmt headers
#include <fmt/core.h>
#include <fmt/format.h>

int main() {
    // Format errors now trigger assert_fail instead of throwing
    fmt::print("Value: {}\n", 42);
}

```

According to the official documentation in [`doc/api.md`](https://github.com/fmtlib/fmt/blob/main/doc/api.md) (lines 87–89), the default value is `1` (exceptions enabled), or `0` when the compiler disables exceptions.

## Error Handling Without Exceptions

When exceptions are disabled, {fmt} replaces exception-based error reporting with an assertion mechanism that offers deterministic termination and optional customization.

### The assert_fail Mechanism

By default, `fmt::assert_fail` writes an error message to stderr and calls `std::abort()`. The function signature matches the standard assertion pattern:

```cpp
void fmt::assert_fail(const char* msg, const char* file, int line);

```

### Custom Assertion Handlers

For projects requiring custom error recovery (such as logging errors or returning error codes), define `FMT_CUSTOM_ASSERT_FAIL` before including headers and provide your own implementation:

```cpp
#define FMT_USE_EXCEPTIONS 0
#define FMT_CUSTOM_ASSERT_FAIL 1
#include <fmt/core.h>
#include <iostream>

void fmt::assert_fail(const char* msg, const char* file, int line) {
    std::cerr << "Format error at " << file << ":" << line 
              << " - " << msg << std::endl;
    // Custom handling: log, set error flag, or throw different type
    std::terminate();  // Required: must not return
}

```

## Practical Code Examples

**Triggering error handling without exceptions:**

```cpp
#define FMT_USE_EXCEPTIONS 0
#include <fmt/format.h>
#include <iostream>

int main() {
    // This valid call works normally
    auto s = fmt::format("Hello, {}!", "world");
    
    // This malformed format string triggers fmt::assert_fail
    // instead of throwing fmt::format_error
    fmt::format("{:d}", "not-a-number");  // Aborts or calls custom handler
}

```

**Complete build command for exception-free static library:**

```bash

# Configure and build fmt without exceptions

git clone https://github.com/fmtlib/fmt.git
cd fmt
cmake -B build -DFMT_USE_EXCEPTIONS=OFF -DFMT_DOC=OFF -DFMT_TEST=OFF
cmake --build build --config Release

```

## Summary

- **Macro control**: Use `FMT_USE_EXCEPTIONS` defined in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) to toggle exception support at compile time.
- **Automatic detection**: {fmt} automatically sets `FMT_USE_EXCEPTIONS=0` when compiled with `-fno-exceptions` or `_HAS_EXCEPTIONS==0`.
- **Three configuration methods**: CMake option (`-DFMT_USE_EXCEPTIONS=OFF`), compiler flag (`-DFMT_USE_EXCEPTIONS=0`), or source-level `#define`.
- **Error redirection**: Disabled exceptions route errors to `fmt::assert_fail`, which can be customized via `FMT_CUSTOM_ASSERT_FAIL` for project-specific error handling.
- **Header-only compatibility**: Exception disabling works identically in `FMT_HEADER_ONLY` mode.

## Frequently Asked Questions

### What happens when FMT_USE_EXCEPTIONS is set to 0?

All internal `TRY/CATCH` macros expand to no-ops, and any formatting error that would normally throw `fmt::format_error` instead calls `fmt::assert_fail`. The program aborts unless you provide a custom handler via `FMT_CUSTOM_ASSERT_FAIL`.

### Can I use fmtlib without exceptions in header-only mode?

Yes. Define `FMT_USE_EXCEPTIONS 0` before including any {fmt} headers when using `FMT_HEADER_ONLY`. The macro controls conditional compilation in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) regardless of whether you link against the compiled library or include headers directly.

### How do I handle errors gracefully when exceptions are disabled?

Implement a custom `fmt::assert_fail` function and define `FMT_CUSTOM_ASSERT_FAIL` before including headers. Your implementation can log errors to external systems, set global error flags, or invoke alternative exception types, but it must not return (typically ending with `std::terminate()` or `std::abort()`).

### Does disabling exceptions improve performance?

Disabling exceptions eliminates the overhead of exception handling tables (`EH tables`) and stack unwinding information, which can reduce binary size and improve cache locality. However, error handling becomes fatal by default, so you should only disable exceptions if your application can tolerate termination on format errors or if you implement `FMT_CUSTOM_ASSERT_FAIL` to handle errors appropriately.