P3953R1 - Rename std::runtime_format WG21
Posted by u/daily_standards_reader · 8 hr. ago

Author: Victor Zverovich
Document: P3953R1
Date: 2026-01-17
Target: LEWG
Link: wg21.link/p3953r1

Victor Zverovich (yes, the {fmt} guy) is proposing to rename std::runtime_format to std::dynamic_format. The motivation is straightforward: now that P3391 made std::format work in constexpr contexts, calling something runtime_format when it can be evaluated at compile time is misleading at best.

The paper argues that the real distinction isn't about evaluation time - it's about how the format string is provided. A "dynamic" format string is one that isn't a compile-time constant, regardless of when the formatting actually happens. This aligns with existing naming in the format library like check_dynamic_spec.

Short paper. Two revisions because R0 had the proposed name wrong in the example, which is kind of poetic for a paper about naming.

▲ 156 points (84% upvoted) · 26 comments
sorted by: best
u/AutoModerator 1 point 8 hr. ago pinned comment

P3953R1 - Rename std::runtime_format

Author: Victor Zverovich | Date: 2026-01-17 | Audience: LEWG

Paper link: wg21.link/p3953r1

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

u/lord_bikeshed 187 points 4 hr. ago 🏆

There are only two hard things in Computer Science: cache invalidation, naming things, and getting LEWG to agree on what to name things.

u/off_by_one_error_43 94 points 3 hr. ago

Three. Three hard things. And off-by-one errors.

u/constexpr_everything 42 points 2 hr. ago

Four. Four hard things. And constexpr making your carefully chosen names wrong.

u/committee_gonna_committee 134 points 5 hr. ago 🏆

This is the most LEWG paper of all time and I mean that as a compliment.

u/actually_reads_papers 89 points 6 hr. ago 🏆

OK so I actually sat down and compared the naming options because this thread is going to turn into a bikeshed anyway, might as well be a structured bikeshed.

runtime_format - Established, shipped in implementations. Contradicts constexpr usage.

dynamic_format - Matches check_dynamic_spec. "Dynamic" overloaded in C++.

unchecked_format - Clear about what it does. Implies no checking, but there IS checking (just deferred).

deferred_format - Accurate re: deferred validation. Nobody says "deferred format string."

dynamic_format is the least bad option. The check_dynamic_spec alignment is the strongest argument in the paper - it means the format library already uses "dynamic" for this concept internally. The paper undersells this point.

The real distinction is not when formatting occurs, but how the format string is provided and validated.

The biggest gap in the paper: it doesn't seriously address unchecked_format as an alternative. "Unchecked" has precedent too. Victor probably has reasons but they're not in the paper.

u/template_wizard_2019 23 points 5 hr. ago

You forgot format_dynamic following the convention where the action comes first. We have to_string, from_chars, etc.

u/embedded_for_20_years 31 points 4 hr. ago

Honestly unchecked_format would be my first choice. It says exactly what the user is doing: opting out of compile-time checking. Whether it runs at "runtime" or is "dynamic" is an implementation detail nobody cares about when they're reaching for this function.

// unchecked_format says what you're DOING
auto msg = std::format(std::unchecked_format(user_input), args...);
// dynamic_format says... what exactly? dynamic how?
auto msg = std::format(std::dynamic_format(user_input), args...);
u/ships_code_daily 52 points 7 hr. ago

I've been using runtime_format in production since our toolchain shipped <format>. Literally nobody on the team was confused by the name. You see runtime_format(some_string) and you understand: "this format string isn't a literal, skip the compile-time check."

The naming "problem" this paper describes is entirely theoretical. Has anyone actually been confused, or is this a purity argument?

u/not_a_professor 71 points 6 hr. ago

Teaching. I teach a C++ course. When I show constexpr format to students and they see runtime_format inside consteval code, the immediate question is "why is it called runtime if we're at compile time?" Every semester. The name actively teaches the wrong mental model.

Despite its name, std::runtime_format can be evaluated at compile time. This creates a semantic mismatch

The paper isn't describing a theoretical problem. It's describing what actually happens when people learn this API without context.

u/ships_code_daily 38 points 5 hr. ago

Fair point on teaching. But dynamic_format isn't much better there - students will draw a parallel to dynamic_cast and think it involves some kind of type-checking mechanism. You're trading one source of confusion for another.

At least with runtime_format you can say "it takes a runtime string" and be done. dynamic_format requires explaining that "dynamic" here means something different from every other use of "dynamic" in the language.

u/not_a_professor 28 points 4 hr. ago

Maybe. But at least "dynamic" doesn't actively contradict what's happening. When a student calls runtime_format in a constexpr function, "runtime" is a lie. "Dynamic" is just vague. I'll take vague over wrong.

u/async_systems_dev 67 points 5 hr. ago

Hot take: runtime_format is still the correct name.

"Runtime" in C++ naming doesn't mean "evaluated at runtime." It means "determined at runtime" - i.e., not a compile-time constant. We say "runtime polymorphism" for virtual dispatch. We say "runtime type information" for RTTI. Nobody argues those names are wrong because you can technically use them in consteval functions.

constexpr auto f(std::string_view fmt, int value) {
    // fmt is a "runtime value" - not a literal
    // the evaluation context doesn't change what it IS
    return std::format(std::runtime_format(fmt), value);
}

As a result, std::runtime_format can now be evaluated at compile time, making its name misleading.

The paper conflates "can be evaluated at compile time" with "is a compile-time value." Those are different things.

u/format_string_enjoyer 45 points 4 hr. ago

Except the standard itself already uses "dynamic" for this exact concept. [basic.format.string] p2 uses "dynamic format specification" for the non-literal case. check_dynamic_spec exists. The naming convention is already dynamic in the format library.

runtime_format is the outlier, not the baseline. This paper is making the library self-consistent, not introducing a new term.

u/build_system_victim 12 points 3 hr. ago

bike. shed.

u/dynamic_cast_survivor 58 points 5 hr. ago

The problem with dynamic_format is that "dynamic" is already overloaded in C++:

- dynamic_cast - runtime type checking + conversion
- dynamic_pointer_cast - shared_ptr variant
- dynamic allocation - heap allocation
- dynamic linkage - shared libraries

In all of these, "dynamic" implies a runtime mechanism with overhead. dynamic_cast can fail. Dynamic allocation goes to the heap. The common thread is "runtime mechanism with cost."

std::dynamic_format isn't any of those things. It's just "I got this format string from a variable." We're borrowing a word that already means something specific in C++ and using it to mean something vaguer.

u/former_boost_contributor 47 points 5 hr. ago

Meanwhile std::execution and networking continue to not exist. But sure, let's spend committee cycles renaming a function that works fine.

u/just_a_cpp_dev 65 points 4 hr. ago

This is a 2-page paper. LEWG can walk and chew gum at the same time. The author spent more time writing it than the committee will spend reviewing it.

u/definitely_knows_what_volatile_does 43 points 4 hr. ago

Worth noting this paper is by Victor Zverovich - the guy who created {fmt} and designed the API that std::format is based on. The original fmt::runtime() in {fmt} predates the standardized version. If anyone has standing to say "we named this wrong," it's him.

Though it's also worth noting that {fmt} itself still uses fmt::runtime(), not fmt::dynamic(). So even Victor's own library uses the old name.

u/segfault_enjoyer 24 points 3 hr. ago

Two revisions to rename a function. This is why C++ standardization takes forever.

u/constexpr_everything 56 points 2 hr. ago

R1 exists because R0 had the wrong name in the "after" example. A paper about naming had a naming mistake. That's art.

u/turbo_llama_9000 15 points 2 hr. ago

just using dynamic_format = std::runtime_format; and stop letting the committee rename your code for you

[deleted] 5 hr. ago

[deleted]

u/oxidize_everything 3 points 1 hr. ago

In Rust the format string is always a literal and this entire category of problem doesn't exist. Just saying.

u/former_boost_contributor 29 points 47 minutes ago

Sir, this is r/wg21.