The post is a 2016 opinionated checklist for writing "Orthodox C++". It says to use C++ as a restrained extension of C, not as a kitchen sink. The advice is to keep syntax simple and predictable, prefer plain structs and free functions, avoid exceptions and RTTI, skip iostreams and allocator-happy standard library features, and be deeply suspicious of template cleverness. In practice it is a style guide for domains where control over memory, latency, codegen, and tooling beats language expressiveness.
That domain framing ended up being the most useful way to read it. People who work in game development and embedded largely said none of this is controversial there. If you are shipping engines, console code, firmware, or other deterministic systems, banning exceptions, RTTI, and hidden allocation is not aesthetic purism. It is scar tissue. Others said the article is old, thin, and badly argued, but still recognizable as the house style many performance-sensitive C++ shops already converged on years ago.
The sharp disagreement was over whether this is a sane subset or a self-inflicted downgrade. Critics pushed back hardest on three things. First, they rejected the broad anti-modern tone. Range-for, lambdas, smart pointers, type inference, and newer compile-time features were treated by many as the genuinely useful parts of C++, not optional decoration. Second, they argued that several complaints target specific bad library designs or historical baggage rather than the language as a whole. Third, they said the post confuses context-dependent constraints with universal rules. Exceptions and RTTI may be unacceptable in tight runtime environments, but for application code they can be the least bad tool available.
A recurring theme was that every serious C++ team ends up defining a subset anyway. The real problem is not whether you use "modern" or "orthodox" C++. It is whether your subset is explicit, enforced, and matched to your workload. The strongest practical criticism of the post was that it stops at slogans. It does not spell out compiler flags, lint rules, replacement libraries, or concrete guidance for where the banned features actually break down. So the useful takeaway people landed on was narrower than the article's posture. Keep the subset small. Make hidden costs visible. But choose the subset from your constraints, not from ideology.
If you run C++ in games, embedded, or latency-sensitive systems, a deliberately small subset still has real operational value. If you are writing application code, libraries, or greenfield systems, treat these rules as context-specific tradeoffs and write down your own subset instead of inheriting someone else's bans.
Mostly mixed to negative. People agreed that small, disciplined C++ subsets are normal and often necessary in games, embedded, and low-latency systems, but many found the article old, under-argued, and too dogmatic about features that are valuable outside those niches.
Key insights
01
Game and embedded constraints drive the subset
What makes this style coherent is not nostalgia for C. It is the operational reality of game engines and embedded systems, where hidden allocation, non-deterministic control flow, and toolchain surprises become production problems. In those environments, avoiding exceptions, RTTI, and parts of the standard library is less about taste and more about making timing, memory use, and debugging behavior predictable.
If your product has hard latency budgets, memory ceilings, or platform certification constraints, write those constraints down first and derive your C++ subset from them. You will get a much more durable style guide than copying a generic "modern" or "orthodox" camp.
The argument over `auto` was really an argument about how code is read. One camp wants types visible in diffs, reviews, and terminal editors because that is where comprehension actually happens. The other camp assumes strong editor tooling and sees repeated type names as noise. That split matters because a style that works in a full IDE can become miserable in code review, patch review, or remote debugging workflows.
Choose type inference rules based on your review and debugging environment, not on taste. If your team reads lots of code outside an IDE, constrain `auto` to cases where the type is obvious from the right-hand side or the loop form.
Complaints about standard containers were not just grumbling about old implementations. Several people pointed out that parts of the standard library are locked into slower designs because the standard promises things like reference stability and specific invalidation behavior. That can rule out faster flat or contiguous data structures, especially for maps and hash maps. The result is that a team can hit real performance ceilings without anyone having written a "bad" implementation.
If container performance matters, do not assume the standard type is close to optimal. Check which guarantees you actually need, then consider non-standard containers that trade away reference stability or other semantics for layout and throughput.
The strongest anti-exception argument was not raw speed. It was that exceptions hide control flow and error contracts. People can tolerate a costly throw path if it is rare. They hate not knowing which calls can fail, what can unwind, and how post-failure debugging will behave. That is why some shops either ban catches entirely or prefer `Result`-style APIs even when exceptions are technically supported.
When designing APIs in C++, decide whether callers should see failure in the type signature. If yes, prefer explicit error-return mechanisms at module boundaries, even if you still allow exceptions internally or in third-party code.
Several comments said the idea would be more credible if it came with flags, linters, and concrete replacements. A subset only works when the toolchain can enforce it and when developers know what to use instead. Without that, "don't use X" decays into folklore and code review arguments. The post feels dated partly because it names prohibitions without packaging the operational playbook around them.
If you adopt a restricted C++ style, turn it into build settings, static analysis checks, and blessed helper libraries. Otherwise the rules will drift and new engineers will re-litigate them feature by feature.
The old complaint that metaprogramming always means unreadable errors is weaker than it used to be. Concepts, `constexpr if`, and `consteval` let libraries fail earlier and in more targeted ways. For teams that lean on compile-time machinery, modern C++ has made heavy generic code more workable than the article suggests.
Do not reject template-heavy designs based on memories of C++11-era diagnostics. Re-evaluate with current compiler support before banning advanced generic techniques across the board.
Invoking Google-style restrictions does not settle the question. Some of those rules were shaped by massive legacy codebases and migration constraints, and even Google says a clean-sheet codebase might choose differently. Meanwhile, people hiring in 2026 reported that modern C++ versions are now standard practice. That weakens the idea that a conservative subset is the obvious default everywhere.
Read large-company style guides as artifacts of their codebase history, not as timeless best practice. For new projects, validate each restriction against your tooling, hiring market, and dependency stack.
A few people treated the whole exercise as evidence that C++ has crossed from flexible to exhausted. If your goal is "better C" or strong systems programming with fewer footguns, Zig, Rust, or even Nim may give you the operational benefits this subset is trying to claw back by convention. That view flips the premise from "which C++ subset" to "why are we still negotiating with C++ at all."
If you are starting greenfield systems work, compare the cost of a custom C++ subset against adopting a language whose defaults already match your safety and predictability goals. The migration cost is not always higher than the long-term policy burden.