# What Is FMT_STRING in {fmt}? Compile-Time Format String Validation Explained

> Understand FMT_STRING in fmtlib fmt. This macro converts string literals to compile-time constants for static validation, catching errors before runtime. Learn more now!

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: deep-dive
- Published: 2026-09-10

---

**`FMT_STRING` is a macro supplied by the {fmt} library that converts string literals into compile-time constants, enabling static validation of format specifiers and catching errors like invalid syntax or type mismatches before runtime.**

`FMT_STRING` is a core feature of the **[{fmt}](https://github.com/fmtlib/fmt)** library (commonly referred to as `fmtlib`) that enables compile-time parsing of format strings in C++. By wrapping your format string with this macro, you leverage constexpr parsing machinery to detect malformed specifiers during compilation rather than at runtime, providing printf-style safety checks with zero performance overhead.

## How FMT_STRING Enables Compile-Time Safety

When you invoke `fmt::format` with `FMT_STRING`, the macro performs two critical functions. First, it **marks the literal as a compile-time constant**, preventing runtime concatenation or dynamic string manipulation. Second, it **triggers static validation**, parsing the format string at compile time to verify that specifiers match the provided argument types.

In compilers supporting C++14 constexpr string parsing and non-type template parameters, `FMT_STRING` expands to `FMT_STRING_IMPL`. On older compilers lacking these capabilities, it falls back to an identity macro that simply returns the literal unchanged, ensuring backward compatibility.

## FMT_STRING Implementation Details

The macro definition resides in **[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)**, where the implementation distinguishes between capable and legacy compilers:

```cpp
/* When compile-time checks are available */
#define FMT_STRING_IMPL(s, base)                                            \
  using FMT_STRING_VIEW = fmt::detail::ignore_unused(                       \
      FMT_STRING_VIEW(FMT_COMPILE_STRING()));                               \
  s

/* In compilers that cannot perform compile-time checks */
#define FMT_STRING(s) s

/* In capable compilers */
#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string)

```

When full compile-time support is available, `FMT_COMPILE_STRING` invokes **`fmt::detail::compile_string_to_view`**, which converts the literal into a `basic_string_view` at compile time. This view is then passed to **`fmt::detail::compile_string`** (defined in **[`include/fmt/detail/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/detail/compile.h)**), a constexpr function that parses the format string and validates specifiers against the argument list.

### Static Validation Mechanics

Inside `compile_string`, the parser builds a compile-time representation of format specifiers. If it encounters illegal specifiers, mismatched braces, or unsupported conversions for the given types, **static assertions trigger immediate compilation errors**. When parsing succeeds, the macro yields the original literal, which the runtime implementation in **`src/format.cc`** uses directly without additional validation overhead.

## Practical Usage Examples

Here is how to use `FMT_STRING` to catch errors at compile time:

```cpp
#include <fmt/core.h>

int main() {
    int n = 42;

    // ✅ Correct – compile-time validated
    std::string s1 = fmt::format(FMT_STRING("The answer is {}."), n);

    // ❌ Compile-time error: unknown conversion specifier 'q'
    // std::string s2 = fmt::format(FMT_STRING("Bad specifier: {q}"), n);

    // ✅ Using different types – all checked at compile time
    std::string s3 = fmt::format(FMT_STRING("Hex: {:#x}, Float: {:.2f}"), n, 3.14);
}

```

In the second example, if your compiler supports constexpr parsing, the illegal `{q}` specifier generates an error during compilation. Without `FMT_STRING`, this mistake would only surface as a runtime exception or undefined behavior.

## Performance Benefits

Using `FMT_STRING` provides **zero runtime overhead**. The format string is parsed exactly once during compilation via the machinery in **[`include/fmt/detail/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/detail/compile.h)**, and the resulting validation is reused for every call. Unlike runtime-checked formatting, this approach eliminates the cost of parsing the format string on every invocation while maintaining complete type safety.

## Summary

- `FMT_STRING` is a macro defined in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) that enables compile-time validation of format strings in the {fmt} library.
- It expands to `FMT_STRING_IMPL` on modern compilers, triggering constexpr parsing via `compile_string_to_view` and `compile_string`.
- Static validation catches illegal specifiers, mismatched braces, and type mismatches before code generation, preventing invalid format strings from reaching runtime.
- On older compilers, the macro falls back to a pass-through identity (`#define FMT_STRING(s) s`), providing backward compatibility without compile-time checks.
- The feature adds zero runtime overhead because parsing occurs entirely at compile time in capable environments.

## Frequently Asked Questions

### What happens if I use FMT_STRING with a non-literal string?

You cannot use `FMT_STRING` with runtime-generated strings or variables. The macro requires a string literal to enable compile-time parsing through `fmt::detail::compile_string`. Attempting to pass a `std::string` or `const char*` variable results in a compilation error because the macro expects a literal that can be processed by the constexpr machinery.

### Does FMT_STRING work with all C++ standards?

`FMT_STRING` works with all C++ standards, but compile-time validation requires support for C++14 `constexpr` string parsing and non-type template parameters. On compilers lacking these features, `FMT_STRING` degrades gracefully to a simple pass-through macro that returns the string literal without static checking, maintaining source compatibility while sacrificing compile-time safety.

### Where is the compile-time parsing logic implemented?

The core parsing logic resides in **[`include/fmt/detail/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/detail/compile.h)** via the `compile_string` function, with entry points and macro definitions in **[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)**. The `compile_string_to_view` utility in [`format.h`](https://github.com/fmtlib/fmt/blob/main/format.h) converts literals into `basic_string_view` instances that the constexpr parser consumes to validate format specifiers against argument types at compile time.

### Can I disable FMT_STRING compile-time checking?

You cannot selectively disable the compile-time checks on supported compilers without modifying the source, but you can simply omit the macro to use runtime validation only. If you wrap your format string with `FMT_STRING`, the library enforces static validation through `FMT_COMPILE_STRING`; if you pass a bare string literal to `fmt::format`, it relies on runtime checks implemented in **`src/format.cc`**.