r/wg21
P4008R0 - Clean Modular Mode: Legacy Opt-out for C++ WG21
Posted by u/evolution_paper_watcher · 7 hr. ago

Document: P4008R0
Author: Zhiyi Lin
Date: 2026-02-08
Audience: EWG
Target: C++29 / C++31

Proposes splitting the standard into three fixed modules: std.core (non-excludable low-level primitives), std.modern (safe modern library), and std.legacy (C compatibility pitfalls like array decay, C-style casts, implicit narrowing). Users opt into "clean mode" with exclude std.legacy. The pitch: keep full backward compatibility by default, let new code opt out of historical baggage per translation unit.

▲ 64 points (78% upvoted) · 18 comments
sorted by: best
u/profiles_already_exist 82 points 6 hr. ago

This is essentially what Profiles (P3970R0, P3984R0) are trying to do, but with a different mechanism. Profiles use compiler-enforced rule sets. This uses module-level opt-out. The DG has already committed to the Profiles framework. I'm not sure EWG will entertain a parallel approach when the committee has repeatedly voted for Profiles as the direction.

u/fresh_perspective_matters 34 points 5 hr. ago

Not every paper needs to align with the DG's preferred framework. The idea of tying safety modes to modules rather than compiler flags is worth exploring even if Profiles win. Different mechanisms can inform each other.

u/array_decay_defender 56 points 6 hr. ago

The vision is appealing but the details are thin. "Array decay is disabled" - what does that mean for functions that take const char*? String literals decay to pointers everywhere. Do you lose string literals in clean mode? The paper doesn't address this. The boundary between "legacy pitfall" and "essential C interop" is much fuzzier than the three-module split implies.

u/c_interop_matters 28 points 5 hr. ago

Exactly. Every C API uses array decay. Every platform header. Every system call wrapper. exclude std.legacy would break interop with the OS unless you exempt FFI boundaries, at which point you need the complexity of Profiles to specify where the rules apply and where they don't.

u/axiom_first_skeptic 47 points 6 hr. ago
Low-level capability ≠ historical garbage
Historical baggage = opt-outable

The axioms are catchy but they assume a clean separation that doesn't exist. reinterpret_cast is low-level and dangerous. Pointer arithmetic is low-level and dangerous. These are in std.core (non-excludable). The paper's own framework means you can't opt out of the most dangerous features.

u/teachability_matters 38 points 5 hr. ago

The "teachable again" angle resonates. New developers starting in clean mode without array decay, C-style casts, or implicit narrowing would have a much better experience. Whether this specific mechanism is the right way to achieve it is debatable, but the goal is worth pursuing.

u/exclude_syntax_concerns 31 points 5 hr. ago

exclude std.legacy as new syntax is a non-starter for C++29. New keywords and syntax additions need EWG review, CWG wording, compiler implementation, and years of transition. The paper targets C++29 Phase 1 but the mechanism requires language changes that typically take two cycles to stabilize.

u/dialect_split_worried 24 points 4 hr. ago

The paper says "not dialect fragmentation." But if clean-mode code can't call legacy-mode code without adapters, and legacy-mode code can't include clean-mode headers that use features legacy mode would reject... that's fragmentation. The interop story needs much more detail.

u/good_intentions_r0 18 points 4 hr. ago

R0 papers are for opening discussion, not for shipping. The vision is clear even if the mechanism needs work. If the author engages with EWG feedback and iterates, the core idea - per-TU opt-out of specific legacy behaviors - could evolve into something useful. Or it could merge into the Profiles effort.

u/module_system_realist 14 points 3 hr. ago

"Builds on C++20 Modules" - but modules control visibility and linkage, not language semantics. Making import std.legacy change which language features are available would be a fundamental extension of what modules do. It's not just "using mature infrastructure."

u/great_another_10_years 8 points 2 hr. ago

The "axioms" section reads like a manifesto. I appreciate the energy but EWG papers usually benefit from less philosophy and more wording.

u/narrow_cast_enjoyer 5 points 1 hr. ago

The code example replaces (int)d with std::narrow_cast<int>(d). That's already best practice. You don't need a module system to enforce it - a linter does the job. The paper is proposing heavy machinery for something clang-tidy already checks.