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.
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.
There are only two hard things in Computer Science: cache invalidation, naming things, and getting LEWG to agree on what to name things.
Three. Three hard things. And off-by-one errors.
Four. Four hard things. And
constexprmaking your carefully chosen names wrong.This is the most LEWG paper of all time and I mean that as a compliment.
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- Matchescheck_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_formatis the least bad option. Thecheck_dynamic_specalignment 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 biggest gap in the paper: it doesn't seriously address
unchecked_formatas an alternative. "Unchecked" has precedent too. Victor probably has reasons but they're not in the paper.You forgot
format_dynamicfollowing the convention where the action comes first. We haveto_string,from_chars, etc.Honestly
unchecked_formatwould 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.I've been using
runtime_formatin production since our toolchain shipped<format>. Literally nobody on the team was confused by the name. You seeruntime_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?
Teaching. I teach a C++ course. When I show constexpr format to students and they see
runtime_formatinside 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.The paper isn't describing a theoretical problem. It's describing what actually happens when people learn this API without context.
Fair point on teaching. But
dynamic_formatisn't much better there - students will draw a parallel todynamic_castand think it involves some kind of type-checking mechanism. You're trading one source of confusion for another.At least with
runtime_formatyou can say "it takes a runtime string" and be done.dynamic_formatrequires explaining that "dynamic" here means something different from every other use of "dynamic" in the language.Maybe. But at least "dynamic" doesn't actively contradict what's happening. When a student calls
runtime_formatin a constexpr function, "runtime" is a lie. "Dynamic" is just vague. I'll take vague over wrong.Hot take:
runtime_formatis 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.
The paper conflates "can be evaluated at compile time" with "is a compile-time value." Those are different things.
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_specexists. The naming convention is alreadydynamicin the format library.runtime_formatis the outlier, not the baseline. This paper is making the library self-consistent, not introducing a new term.bike. shed.
The problem with
dynamic_formatis 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_castcan fail. Dynamic allocation goes to the heap. The common thread is "runtime mechanism with cost."std::dynamic_formatisn'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.Meanwhile
std::executionand networking continue to not exist. But sure, let's spend committee cycles renaming a function that works fine.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.
Worth noting this paper is by Victor Zverovich - the guy who created {fmt} and designed the API that
std::formatis based on. The originalfmt::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(), notfmt::dynamic(). So even Victor's own library uses the old name.Two revisions to rename a function. This is why C++ standardization takes forever.
R1 exists because R0 had the wrong name in the "after" example. A paper about naming had a naming mistake. That's art.
just
using dynamic_format = std::runtime_format;and stop letting the committee rename your code for you[deleted]
In Rust the format string is always a literal and this entire category of problem doesn't exist. Just saying.
Sir, this is r/wg21.
tell me you've never shipped production code without telling me you've never shipped production code. who cares what the function is called, just ship it