HN Debrief

Orthodox C++ (2016)

  • Programming
  • Developer Tools
  • Open Source

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.

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.

Discussion mood

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

  1. 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.

      Attribution:
    • flohofwoe #1
    • forrestthewoods #1
    • kabdib #1
    • AnimalMuppet #1
  2. 02

    Auto and inference expose an IDE divide

    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.

      Attribution:
    • PaulDavisThe1st #1 #2
    • badsectoracula #1
    • wk_end #1
    • preg_match #1
  3. 03

    Some STL pain is baked into guarantees

    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.

      Attribution:
    • jcranmer #1
    • wavemode #1
    • tialaramex #1
  4. 04

    Exceptions are really a visibility problem

    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.

      Attribution:
    • forrestthewoods #1
    • patrick451 #1
    • cpgxiii #1
    • canyp #1
  5. 05

    The missing piece is enforcement

    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.

      Attribution:
    • canyp #1
    • fithisux #1
    • aw1621107 #1
    • rramadass #1

Against the grain

  1. 01

    Template ergonomics have improved a lot

    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.

      Attribution:
    • fluoridation #1
    • nly #1
  2. 02

    Big-company bans are not universal guidance

    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.

      Attribution:
    • demorro #1
    • patrick451 #1
    • cpgxiii #1
    • otabdeveloper4 #1
  3. 03

    The better answer may be another language

    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.

      Attribution:
    • wseqyrku #1
    • yyx #1
    • netbioserror #1

In plain english

consteval
A C++ feature that requires a function to be evaluated at compile time.
constexpr
A C++ feature for computing values at compile time when possible.
IDE
Integrated development environment, a coding application with editing, debugging, and build tools.
RTTI
Run-Time Type Information, a C++ feature for inspecting object types at runtime.

Reference links

Style guides and related writeups

RTTI and type system alternatives

  • LLVM-style RTTI guide
    Shared as an example of a hand-rolled RTTI approach used in LLVM instead of built-in RTTI.
  • royvandam/rtti
    Offered as a faster custom RTTI implementation using templates and macros.

Allocators and memory management examples

Books and talks

Coroutines and language comparisons