Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- Nothing surprising here. People who view C++ as just a better C always outnumbered those who view it as another language.
That's exactly how democratic governments make their decisions… you might think it's stupid, and you'd be right, but that's democracy. It's the majority that counts, not what's right. At least you can have a little fun with their arguments, they're pretty inventive you know.
- I've been doing embedded systems in C++ since rocks were young, and this is a great summary of what to avoid.
I would sure love a good coroutine runtime, and first-class support for defer. You can do these manually, but language/toolchain/debugger support is nice to have.
(Pragmatically, I will be retired by the time they would be useful)
by kabdib - It is still a bit amazing to me that it was significantly easier to do coroutines in Sigma 5 assembly and likely most any assembly than in C or C++. Two languages supposedly close to the machine.by wglb
- A defer is just a dozen lines of code nowadays, if you really need it, but in most cases you don't if you're doing RAIIby usrnm
- In embedded, I like wrapping a class around a set of registers. Nobody else gets to write to that piece of hardware except that class.
As far as avoiding things... avoid basically everything you don't need. Don't add language features that don't actually help you, just because they're there. Keep the subset you use small. But pick that subset to match your problem well, rather than out of dogma.
by AnimalMuppet - > Don’t use RTTI.
That's the core feature of the language. Not using it doesn't make any sense.
> Don’t use stream (<iostream>, <stringstream>, etc.), use printf style functions instead.
printf is type-unsafe and bug-prone. Also modern C++ standards have better formatting utilities.
> Don’t use anything from STL that allocates memory, unless you don’t care about memory management.
In 99.9% of the time one should not care. Using something like std::vector is perfectly fine.
Overall I find such "Orthodox" C++ harmful. I call it "pure C heresy".
by Panzerschrek - The criticisms of STL and allocation are fair, though move constructors improved the shallow vs deep copy problem on resize.
Smart pointers are good. People were doing them outside the standard in the late 90s.
Lambdas are a good feature.
by asveikau - I'm not opposed to the concept, but the definition is problematic:
> Orthodox C++ (sometimes referred as C+) is minimal subset of C++ that improves C, but avoids all unnecessary things from so called Modern C++. It’s exactly opposite of what Modern C++ suppose to be.
"Modern C++" is usually considered to mean the significant changes to the language in 2011, or 2011 and later. The thing is, that a "small subset improving over C", and without "unnecessary things" will not necessarily avoid 2011-and-later language features, and splurge with pre-2011 features. And this becomes clear as you read the recommendation. So, it's recommand to avoid:
* exceptions
* STL objects which allocate memory
* C++ streams
all C98 features. On the other hand, it's not recommended to avoid constexpr, and it is in fact hinted it is useful.
-----
C++ is a multi-paradigmatic language. It has lots of features, in the language and via the standard library. It is perfectly reasonable and legitimate to pick feautres which are well-tested enough; or well-regarded by, say, embedded or game developers, or doesn't seem too outlandish coming from C. Of course, different people will quibble over what exactly to adopt or discard, but I'm sure that different flavors of "orthodox C++", "sane C++", etc. are in fact used by many groups of developers.
by einpoklum - Such a missed opportunity to call it C <orthodox cross emoji>by nasretdinov
- that's one way to combine three plus signs!by undershirt
- Was thinking "Hesitance C" could workby greenbit
- stringstreams and fmt are a godsend compared to printf/scanf, which have historically led to most memory bugs in the first place!
Printf/scanf are implemented as variadic functions without type checking and rely on the compiler to perform its own internal metaprogramming to inspect and warn about format mismatches.
Anyone advocating the use of the old cstdio as a primary design decision about which C++ language features to use is not serious.
No exceptions or RTTI make sense in an embedded system that needs to ensure determinism, but are arbitrary and unnecessarily hobbling for high-level systems and application programming. How do you do runtime method dispatch without creating vtables and RTTI from first principles? How do you propagate a runtime error deep from the bowels of a component all the way to some top-level event loop? The "orthodox" approach would be a mess of integer return codes with associated enums (and none of that enum class nonsense!). No Thanks. It's clear the author has no idea what he's talking about.
by ok123456 - You can take
from my cold dead hands.for (auto const & ess : esses) { ... }Also, you can fight me if you want to take
and force me to implement my own typing system every time I need to upcast.dynamic_cast<Derived> (base_ptr)Basically, stick with C and leave C++ programmers alone. I haven't seen a less useful article about C++ in a long time, and as an HN reader, that's really saying something.
- Implementing STL iterators are a bloody PITA
- LLVM uses a hand-rolled version of RTTI for the best performance (the parent constructor accepts its runtime type as an enum), and it seemed that the maintenance costs for it aren't that high. (See https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html)
Or if you're even lazier, you can easily make a more automatic RTTI system with some templates / macros that works much faster than dynamic_cast! (See https://github.com/royvandam/rtti)
- > for (auto const & ess : esses) {
The problem with this is that whoever is reading the code as-is does not know what type "ess" is. Sometimes you get the definition somewhere nearby, in which case it is probably fine - assuming it is close enough that it'll be included in a diff - but more often than not you don't know.
Yes, an IDE can probably tell you (probably, depends on the IDE and assuming everyone uses one) but even that requires some extra action like moving the mouse over the definition and hoping it'll give you something. However this wont show up in diffs, PRs, code reviews, etc.
IMO `auto` is one of those C++ features that really needs discipline to use - and when in doubt, i'd rather ban its use (except where you cannot do otherwise) than rely on everyone doing the right thing.
- > for (auto const & ess : esses) {
This is allowed by Orthodox C++
> dynamic_cast<Derived> (base_ptr)
This isn't because it requires RTTI, but dynamic_cast is also a typical code smell.
Orthodox C++ isn't generally against new C++ features, it only advices to wait about 5 years (or at least one C++ version) for stabilization and to apply some common sense before adopting them.
The notes about not using RTTI, exceptions and stdlib features that allocate under the hood are all justified by painful experience with those things in the context of game development.
In general, the restrictions outlined in the post make a lot of sense when considering that Branimir (of BGFX fame: https://github.com/bkaradzic/bgfx) is coming out of the game dev hemisphere, and from that PoV none of the restrictions are controversial - on the contrary, it would be highly controversial to suggest going all in on Modern C++ features ;)
by flohofwoe - One thing I've noticed about a lot of these "strict C" developers is that quite often they actually refuse to learn C++. One of the most common complaints of C developers regarding C++ is "it does things behind the scenes/performs magic", often with regards to operator overloading. When they refuse to actually look at the implementation (y'know you can check if an operator has been overloaded) AND they refuse to acknowledge that a huge chunk of "pure C" does HEAPS of magic behind the scenes (that the developer has no idea about) unless they've actually studied the spec in detail. Malloc and memory allocation methods are at least 10k+ lines of code for instance.by rfgplk
- My codebase uses a fairly dumbed down version of C++, but I would have liked to see more depth in this post. As it is, it is not very useful.
There are many more things to avoid than just iostream. HFT university has a good recap: https://hftuniversity.com/post/the-c-standard-library-has-be...
The point on exceptions I think is also misleading. Compilers typically make throwing an exception the expensive part, and the happy path inexpensive (not more expensive than a branch checking for errors, which should be the baseline for comparison, not an implementation with zero error checking.) So to say that they are "expensive" doesn't really make a useful argument.
And there are more things that could be done in this camp, like proposing a set of compiler flags, and a linter to enforce the subset you are subscribing to. Unfortunately the post offers none of that.
by canyp - AI slop article.by Chaosvex
- > There are many more things to avoid than just iostream.
But even "avoiding iostream" is stupid. The author presumably really means "avoid operator>> and operator<< for I/O". Even using type-safe printf-like stuff ultimately still sits on top of iostream.
- [from the linked article]
> <deque>: Needs a major performance overhaul", acknowledging that the standard's mandated block size is too small and the design needs to be rebuilt at the next ABI break
Except of course the standard does not mandate a block size. That's purely msvc picking a wrong block size and being stuck with it.
The rant about lists is also nonsense.
by gpderetta - Submitted a fair few times previously. HN's search turned up these submissions with some additional discussion:
https://news.ycombinator.com/item?id=40445536 (2 years ago, 63 points, 66 comments)
https://news.ycombinator.com/item?id=25554018 (5 years ago, 70 points, 102 comments)
https://news.ycombinator.com/item?id=13751244 (9 years ago, 29 points, 14 comments)
Looks like the page was moved from a GitHub gist to a github.io page in October of last year.
by aw1621107 - Yep, the article is a old one and not particularly well written. As somebody who has been using C++ from the early 90s and not particularly a fan of (all of) "Modern C++", there is not much information here.by rramadass
- If you're in a market that requires using C++, many of these decisions are made for you by the platform above you, and you're screwed. Turn on RTTI, build a fort to deflect the random exceptions they'll throw at you, and may the gods allow you to recoup your R&D before some well-intentioned yokel in some media or game vertical changes everything and requires you to change everything.
On the other hand, if you control your own destiny and care about velocity and code quality, many of these choices eventually become self-evident.
If you are messing around with the latest and greatest esoteric C++ stuff in 2026, bless you, you beautiful nerd. But it may be time to start evaluating where you are in life, and how you got here. (And if you're on a C++ committee, I revoke those blessings.)
For those who remain: if you have a C++ code base yet somehow have enough time and energy to write opinionated blog posts, it's really hard to imagine why you think you'd have a better take on this than Google.
by badlibrarian - > it's really hard to imagine why you think you'd have a better take on this than Google.
Do you mean this as an appeal to Google being the home to great talent, or more as an endorsement of the specific guidance provided by this specific style guide, Google or no?
Because if the former, I think I do almost everything better in my context than Google would. It would be hard not to considering the difference in organizational scale.
by demorro - I interview C++ developers often, and here in 2026 it seems pretty much everyone is using modern (C++20 and up) language versions.
Maybe the tooling finally caught up.
- > build a fort to deflect the random exceptions they'll throw at you
Sounds like you hate exceptions, right? In which case why do you handle them at all? Just leave them all unhandled and suddenly every exception is a crash. Which is really no different from someone choosing to terminate. Which you have to worry about even without exceptions.
> if you have a C++ code base yet somehow have enough time and energy to write opinionated blog posts, it's really hard to imagine why you think you'd have a better take on this than Google.
"Given that Google's existing code is not exception-tolerant [...] Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. [...] Things would probably be different if we had to do it all over again from scratch."
by dataflow - I've developed a style that I legitimately call Heterodox C++ (mainly due to the popularity of Orthodox C++), it is effectively a purely functional & metaprogramming heavy style of C++. Quite the opposite of this, not everyones cup of tea, and it won't fit into every codebase but it is incredibly powerful. The template metaprogramming C++ offers is the most powerful of any imperative language, and (subjective opinion) is second only to Lisp, but few people make use of it. With some of C++26 features you can almost even replicate most of Rusts safety features in pure C++ (via function tagging + reflection)by rfgplk
- C++ template metaprogramming is in some ways more powerful than Common Lisp macros, because it works at the type level: you can generate new types and dispatch into separate implementations by type. In contrast, Common Lisp type declarations are not available at macro expansion time unless you implement a full source-to-source translator in macros.by unnah