# What Is dynamic_format_specs in fmtlib and How Does It Work

> Learn about dynamic_format_specs in fmtlib. This struct extends format_specs, allowing deferred resolution of width and precision from runtime arguments. Understand its functionality and implementation.

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

---

**`dynamic_format_specs` is a template struct in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) that extends the standard `format_specs` class with two `arg_ref` members—`width_ref` and `precision_ref`—enabling deferred resolution of width and precision values from runtime arguments.**

The `{fmt}` library (also known as `fmtlib/fmt`) supports dynamic format specifications where field width and precision are determined at runtime rather than compile time. This capability is implemented through the `dynamic_format_specs` structure, which decouples format string parsing from value resolution to enable format string reuse and pre-compilation.

## Defining dynamic_format_specs in core.h

The `dynamic_format_specs` template is defined at lines 1286-1290 in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h). It inherits from `format_specs` and adds two additional members that store references to arguments rather than concrete integer values.

```cpp
template <typename Char = char>
struct dynamic_format_specs : format_specs {
  arg_ref<Char> width_ref;
  arg_ref<Char> precision_ref;
};

```

This design allows the format parser to record *where* to find the width and precision values (either by index or name) without actually fetching the values during the initial parse phase.

### The arg_ref Mechanism

The `width_ref` and `precision_ref` members are instances of `arg_ref<Char>`, a variant-like template class that can hold either:

- An integer index referring to a positional argument
- A string identifier referring to a named argument

When the parser encounters dynamic syntax like `"{:{}}"` or `"{:{precision}}"`, it populates these `arg_ref` objects with the appropriate reference instead of storing the immediate numeric value in the base `format_specs` structure.

## How Dynamic Format Specifications Work

### Parsing Dynamic Width and Precision

When parsing a format string containing runtime-dependent width or precision, the library creates a `dynamic_format_specs<>` instance rather than a plain `format_specs`. According to the unit tests in `test/core-test.cc` (lines 506-508), the parser identifies dynamic fields by detecting empty braces `{}` or named references within the format specification portion of the format string.

For example, in the format string `"{:*>{}}"`:
- The `*` character specifies a fill character
- The `>` specifies right alignment
- The second `{}` indicates that the width should be taken from the next argument

The parser stores this reference in `specs.width_ref` without evaluating the actual integer value.

### Runtime Resolution with resolve_dynamic_spec

During the formatting phase, the library resolves these dynamic references through internal helpers such as `detail::resolve_dynamic_spec` (implemented in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)). This function:

1. Examines `specs.width_ref` or `specs.precision_ref`
2. Retrieves the actual integer value from the argument store using the stored index or name
3. Assigns the resolved value to the base class members `specs.width` or `specs.precision`
4. Proceeds with standard formatting using the now-concrete values

This deferred resolution architecture is critical for `dynamic_format_arg_store` (defined in [`include/fmt/args.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/args.h)), which allows building argument lists programmatically while reusing pre-parsed format specifications.

## Practical Implementation Example

The following example demonstrates manual construction and usage of `dynamic_format_specs` to format a string with runtime-determined width and precision:

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

int main() {
  // Create dynamic format specifications
  fmt::detail::dynamic_format_specs<char> specs;
  
  // Configure dynamic references: width from argument 1, precision from argument 2
  specs.width_ref = fmt::detail::arg_ref<char>(1);
  specs.precision_ref = fmt::detail::arg_ref<char>(2);
  specs.align() = fmt::align::right;
  
  // Prepare arguments: value, width, precision
  auto args = fmt::make_format_args(3.14159, 10, 2);
  
  // Format with dynamic specifications
  std::string result = fmt::detail::vformat("{:{}}", args, specs);
  // Result: "      3.14" (width 10, precision 2, right-aligned)
  
  return 0;
}

```

In this example, the same `specs` object can be reused with different argument sets, demonstrating the efficiency gains of separating parsing from value resolution.

## Benefits of Using dynamic_format_specs

**Performance Through Pre-compilation**: Because `dynamic_format_specs` stores references rather than values, parsed format strings can be cached and reused with different argument sets without re-parsing the format string syntax.

**Support for FMT_COMPILE**: Dynamic specifications work with compile-time format strings (`FMT_COMPILE`), allowing the library to validate format syntax at compile time while still permitting runtime-determined field widths and precisions.

**Flexibility with Named Arguments**: The `arg_ref` mechanism supports both positional indices and named references, enabling expressive APIs where users specify precision via names like `"{value:{precision}}"` rather than numeric indices.

## Summary

- `dynamic_format_specs` extends `format_specs` in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h) (lines 1286-1290) with `width_ref` and `precision_ref` members.
- The struct uses `arg_ref<Char>` to store references to arguments supplying dynamic width and precision values.
- Resolution occurs at formatting time via `detail::resolve_dynamic_spec` in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), fetching actual values from the argument store.
- This architecture enables format string pre-compilation and reuse with `dynamic_format_arg_store` from [`include/fmt/args.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/args.h).
- Implementation supports both positional (`{}`) and named (`{name}`) dynamic references while maintaining compatibility with compile-time format string validation.

## Frequently Asked Questions

### What is the difference between `format_specs` and `dynamic_format_specs`?

`format_specs` stores concrete formatting parameters such as fill character, alignment, and static width/precision as immediate values. `dynamic_format_specs` inherits from `format_specs` but replaces static width and precision with `arg_ref` objects that store references to runtime arguments, allowing the same parsed specification to be used with different numeric values across multiple formatting operations.

### How does fmtlib resolve dynamic width at runtime?

The library invokes internal helpers like `detail::resolve_dynamic_spec` during the formatting phase. This function inspects the `width_ref` member of the `dynamic_format_specs` object, retrieves the corresponding integer value from the argument list (whether stored by index or name), and assigns that value to the base class `width` member before the actual formatting output is generated.

### Can `dynamic_format_specs` be used with compile-time format strings?

Yes. The separation of parsing and resolution allows `dynamic_format_specs` to work with `FMT_COMPILE` and other compile-time format string features. The format string syntax is validated at compile time, while the actual width and precision values are fetched from arguments at runtime, providing both safety and flexibility.

### Where is `dynamic_format_specs` defined in the source code?

The template struct is defined at lines 1286-1290 in [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h). Related parsing logic appears in [`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), while usage examples and unit tests are located in `test/core-test.cc` (specifically around lines 506-508). The complementary `dynamic_format_arg_store` class is defined in [`include/fmt/args.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/args.h).