# What Is the FMT_COMPILE Macro and How to Use It in {fmt}

> Discover the FMT_COMPILE macro for compile-time format string parsing in fmtlib. Eliminate runtime overhead and boost performance with this powerful tool.

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

---

**The `FMT_COMPILE` macro converts a format string literal into a compile-time parsed representation, eliminating runtime parsing overhead by generating code that directly formats arguments.**

The `FMT_COMPILE` macro is the entry point for {fmt}'s compile-time format string feature in the `fmtlib/fmt` repository. This optimization moves format string parsing from runtime to compile time, resulting in faster execution and smaller binary sizes for performance-critical applications. When you wrap a string literal with this macro, the library generates specialized formatting code instead of interpreting the format string at runtime.

## Understanding the FMT_COMPILE Macro Definition

The `FMT_COMPILE` macro is defined in [[`include/fmt/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h) and serves as the user-facing interface for compile-time formatting. Its implementation depends on your compiler's C++ standard support.

### Compiler Requirements and Conditional Definition

The macro uses conditional compilation to detect C++17 capabilities. According to the source code in [`include/fmt/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h) (lines 38-40), the definition checks for `__cpp_if_constexpr` and `__cpp_return_type_deduction`:

```cpp
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)

#  define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string)

#else

#  define FMT_COMPILE(s) FMT_STRING(s)

#endif

```

When your compiler supports C++17 `if constexpr` and return-type deduction, `FMT_COMPILE` expands to `FMT_STRING_IMPL` with `fmt::compiled_string` as the second argument. This creates a **compiled string** type that encodes the parsed format at compile time. On older compilers, the macro gracefully degrades to `FMT_STRING`, preserving source compatibility while falling back to runtime parsing.

### The Compile-Time Pipeline

Under the hood, `FMT_STRING_IMPL` (defined in [[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)) constructs a lightweight wrapper type that marks the literal as a compiled string. This type satisfies the **`is_compiled_string`** trait (`fmt::detail::is_compiled_string`), which overloads in `fmt::format` detect to trigger the compile-time path (lines 54-57 in [`compile.h`](https://github.com/fmtlib/fmt/blob/main/compile.h)).

When `fmt::format` receives a compiled string, it invokes `detail::compile<T...>(S{})` (around line 554 in [`compile.h`](https://github.com/fmtlib/fmt/blob/main/compile.h)) to produce a **templated compile-time format representation**. This representation allows the library to emit machine code that writes formatted output directly, bypassing the runtime parser entirely.

## How to Use FMT_COMPILE in Your Code

Using the macro requires including the compile-time header and wrapping your format strings. Here is a complete example demonstrating the difference between runtime and compile-time formatting:

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

int main() {
    // Classic runtime parsing – incurs parsing overhead
    std::string a = fmt::format("{} + {}", 1, 2);
    
    // Compile-time parsing – zero runtime format-string work
    std::string b = fmt::format(FMT_COMPILE("{} + {}"), 1, 2);
    
    // Both produce "1 + 2", but 'b' executes faster
    return 0;
}

```

The key difference is that `FMT_COMPILE("{} + {}")` creates a type that encodes the two replacement fields and the literal text `" + "` at compile time. The resulting binary contains code that directly writes the integer arguments and the separator without interpreting a format string at runtime.

### The C++20 _cf Literal Operator

When compiling with C++20 non-type template parameter support (`FMT_USE_NONTYPE_TEMPLATE_ARGS`), {fmt} provides an even more ergonomic syntax via the user-defined literal `_cf`:

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

using namespace fmt::literals;

int main() {
    // Equivalent to FMT_COMPILE("{} + {}")
    std::string c = fmt::format("{} + {}"_cf, 1, 2);
}

```

This literal operator expands to `FMT_COMPILE` internally, offering cleaner syntax for modern C++ projects. You can check if this feature is available by testing for the `FMT_USE_NONTYPE_TEMPLATE_ARGS` macro.

## Performance Benefits of Compile-Time Formatting

**Zero runtime parsing** is the primary advantage of using `FMT_COMPILE`. Standard `fmt::format` calls must parse the format string, validate arguments against format specifiers, and dispatch to formatting routines at runtime. With `FMT_COMPILE`, the compiler performs these steps during translation, resulting in:

- **Reduced binary size** for repeated formatting operations (the format string logic is compiled once per unique format)
- **Eliminated branch mispredictions** from the format parser
- **Inlining opportunities** across the formatting boundary

However, because `FMT_COMPILE` instantiates templates based on the format string contents, it can increase compile times and binary size if used with thousands of unique format strings in the same translation unit.

## Summary

- **`FMT_COMPILE`** is defined in [`include/fmt/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h) and converts string literals into compile-time parsed format representations.
- The macro requires C++17 `if constexpr` support for full functionality; otherwise, it degrades to `FMT_STRING`.
- **Compiled strings** trigger specialized overloads in `fmt::format` that call `detail::compile` to generate direct formatting code.
- The **`_cf`** literal operator provides syntactic sugar for C++20 projects when `FMT_USE_NONTYPE_TEMPLATE_ARGS` is enabled.
- Use this feature for hot paths where format strings are known at compile time and maximum performance is required.

## Frequently Asked Questions

### What is the difference between FMT_COMPILE and FMT_STRING?

`FMT_STRING` validates format strings at compile time but still performs runtime parsing when formatting. `FMT_COMPILE` goes further by parsing the format string during compilation and generating code that writes output directly without runtime interpretation. `FMT_COMPILE` produces faster code but requires C++17 features, while `FMT_STRING` works with older standards.

### Does FMT_COMPILE work with dynamic format strings?

No. `FMT_COMPILE` only accepts string literals known at compile time. If you need to format strings constructed at runtime (such as user input or configuration files), you must use the standard `fmt::format` runtime interface. Attempting to pass a `std::string` or `const char*` variable to `FMT_COMPILE` will result in a compilation error.

### Will using FMT_COMPILE increase my binary size?

It depends on usage patterns. For a few dozen unique format strings, `FMT_COMPILE` typically reduces binary size by eliminating parser code and runtime format tables. However, because each unique format string instantiates distinct template code, using thousands of different format strings in one translation unit can increase binary size significantly compared to the runtime approach.

### Which compilers support full FMT_COMPILE functionality?

Any compiler with C++17 support for `if constexpr` and return-type deduction enables the full `FMT_COMPILE` implementation. This includes GCC 7+, Clang 5+, and MSVC 2017+. The macro automatically detects support via the `__cpp_if_constexpr` and `__cpp_return_type_deduction` feature test macros and falls back to `FMT_STRING` behavior on older compilers.