Need help?
<- Back

Comments (158)

  • rfgplk
    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)
  • aw1621107
    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.
  • canyp
    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.
  • badlibrarian
    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.https://google.github.io/styleguide/cppguide.html
  • PaulDavisThe1st
    You can take for (auto const & ess : esses) { ... } from my cold dead hands.Also, you can fight me if you want to take dynamic_cast<Derived> (base_ptr) and force me to implement my own typing system every time I need to upcast.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.
  • ok123456
    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.
  • nasretdinov
    Such a missed opportunity to call it C <orthodox cross emoji>
  • asveikau
    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.
  • kabdib
    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)
  • Martin_Silenus
    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.
  • amomchilov
    No benefits to modules? Oh come on.Hard to take seriously.
  • greenbit
    Sometimes I actually want objects that are transparent, fully public, and 'struct' is perfect for that. But if I then go and put methods into those structs, does that make me unorthodox?
  • gpderetta
    Don't follow dogma.
  • yyx
    At this point, if you want better C, just use Zig.
  • BiraIgnacio
    Holly bananas, that Boost Design Rationale post is, what's the word I'm looking for, intense.
  • rfgplk
    This is gonna be a long critique, I'll try to keep it concise.> C-like C++ is good start, if code doesn’t require more complexity don’t add unnecessary C++ complexities.C is almost obsolete nowadays. Not to mention that C++ is effectively a strict superset of C (nearly 99% of the C standard is in C++) and the few features that aren't are included as compiler extensions (VLA, restrict keyword, nested functions). There are a handful of C features that aren't in C++, and for very good reason (most of them suck). When was the last time you ran into a C library that a pure C++ compiler couldn't compile? Only if someone decided to spam the new keyword all over the codebase (or something similar).> In general case code should be readable to anyone who is familiar with C language.Most C++ already is? Even very template heavy C++.> Don’t do this, the end of “design rationale” in Orthodox C++ should be immedately after “Quite simple, and it is usable. EOF”.A lot of the methods in that document are necessary to make C++ shine, especially template metaprogramming.> Don’t use exceptions.Optional but irrelevant.> Don’t use RTTI... Why? Reimplementing RTTI in C will give you almost the same overhead.> Don’t use C++ runtime wrapper for C runtime includes (<cstdio>, <cmath>, etc.), use C runtime instead (<stdio.h>, <math.h>, etc.).. Why? Those wrappers all include the "raw C runtime" under the hood (literally they do #include <stdio.h|xx>. Near 0 compiletime overhead?> Don’t use stream (<iostream>, <stringstream>, etc.), use printf style functions instead.This is a design decision.> Don’t use metaprogramming excessively for academic masturbation. Use it in moderation, only where necessary, and where it reduces code complexity.There are many programs that are _impossible_ to write in a finite time without metaprogramming. How will you (with zero runtime overhead) dispatch a function with a variable arity of random types to a handler that requires exactly that type of function? Arbitrarily? In C++ it's possible, in C it isn't.
  • wseqyrku
    Might as well use Rust. Basically if you have a choice, using C++ over Rust is kind of stupid in 2026, to be honest.
  • sudosteph
    And here I was thinking this was going to be about a schism from Holy C [1][1] https://en.wikipedia.org/wiki/TempleOS#HolyC
  • aleksiy123
    Somewhere within c++ there is a subset of c++ that is a great language.The problem of course is that no one agrees on which subset that is.
  • jstimpfle
    Orthodox C++, to me, is C plus the one good feature of C++: you don't have to type struct all the time.
  • fithisux
    I wish the site listed compiler flags for the most popular compilers.
  • einpoklum
    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++ streamsall 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.
  • netbioserror
    Man, all of the confusion and gnashing of teeth in the C++ world really makes me grateful for my job. Smaller company, I solo develop a central module on the product stack, and I was able to evaluate languages for the project.Nim became the obvious choice, and I wasn't a fanboy before. Simple semantics, in a very functional style oriented around data's value. References and identity have to be trapdoored. Everything is single-owner unique lifetimes by default, no annotations or best-practices required. You end up writing extraordinarily functional/procedural code that produces very fast and memory-safe binaries, it fits right into C++'s niche.The only objection I could steel man was that the standard library and most packages are composed of relatively pure functions that return new values, so allocations are happening there. But when types as complex as data frames can be semantically used as just values, and you know they have scoped lifetimes by default, the benefits are obvious.With all of C++'s insanely specific, subtle, implicit, compiler- and platform-dependent behaviors, I've often wondered when the industry will finally consider its dominance an artifact of first-mover inertia and simply move on. There are vastly better ways to do all of the things it does, while easily exposing levers for the the things it's considered to do exceptionally well.