We were surprised when we read a post from C++ creator [Bjarne Stroustrup] that reminded us that C++ is 45 years old. His premise is that C++ is robust and flexible and by following some key precepts, you can avoid problems.
We don’t disagree, but C++ is much like its progenitor, C, in that it doesn’t really force you to color inside the lines. We like that, though. But it does mean that people will go off and do things the way they want to do it, for any of a number of good and bad reasons.
![](https://hackaday.com/wp-content/uploads/2025/02/b-s-1.jpg?w=400)
We will admit it. We are probably some of the worst offenders. It often seems like we use C++ the way we learned it several decades ago and don’t readily adopt new features like auto variables and overly fancy containers and templates.
He proposes guidelines, including the sensible “Don’t subscript pointers.” Yet, we are pretty sure we will, eventually. Even if you are going to, also, it is still worth a read to see what you ought to be doing. We were hoping for more predictions in the section entitled “The Future.” Unfortunately — unlike Hackaday authors — he is much too smart to fall for that trap, so that section is pretty short. He does talk about some of the directions for the ISO standards committee, though.
We should have known about the 45 years, as we covered the 30th birthday. We like safer code, but we disagree with the idea that C++ is unsafe at any speed.
Photograph by [Victor Azvyalov] CC-BY-SA-2.0.
Obligatory Stroustrup interview link:
https://www.ganssle.com/tem/tem17.htm
Reading just the first few paragraphs from the post that is the subject of this article, that older “interview” seems plausible.
“We are probably some of the worst offenders. It often seems like we use C++ the way we learned it several decades ago and don’t readily adopt new features like auto variables and overly fancy containers and templates.” .. probably its the best to skip C++ and go directly to RUST ;-)
Or skip Rust and wait for the next one, it seems a trend that new programming languages are invented continuously. And none of them really fix the real problem: sloppy programmers and bad quality assurance (programming practices, code review, testing ..).
And maybe skip programming altogether and wait for few years as most of programming is done by prompting AI.
New languages come and go, but C and C++ seem to stay ..
Just learn Rust. It’s designed specifically to fix those.
Except much of the Rust libraries needed to build real applications is not memory safe. And not data race safe.
Yesterday I learned that there is a funded effort to formely verify the rust libraries and provide the tools for other code.
How is rust better then ADA?
yes. By a large margin…
How about. I stead of inventing better programming languages, we develop better programmers?
I’ve been in the business over 30 years, and the quality of course code is abysmal. And it’s getting worse.
Requirements suck. No meaningful design is done. Basic best practices are ignores or unheard of. Code reviews are a rubber-stamp process. Mentoring is unheard of and even if it were a thing, the guys who DO know better are retiring.
Model-driven development only serves to further insulate the author from the problem, should one occur. Debugging model-based code can be like playing the piano with mittens on.
Put your big-boy pants on and get the basics RIGHT before trotting off to the next shiny new toy that promises to solve all hour problems, most of which aren’t even related to the language.
Reminds me of when Java was supposed to be a panacea with its garbage collector.
rust is absolutely trash that aint stable enough even for linux kernel. rust is used by teenagers trying to be edgy and not a single big serious software company uses it
Literally everything one can do in rust can be done in standard c++. Otherwise not.
at this point learning a new programming language is probibly a lot easier than learning all the new stuff c++ has.
Never forget that there are valid and conforming C++ programs that can never be compiled, because compilation takes an infinite time. The C++ designers refused to understand and recognise that until Erwin Unruh rubbed their faces in a program 30 years ago.
Unruh created a (valid, conforming) C++ program that causes the compiler to generate the sequence of prime numbers during compilation. Since that sequence is infinite, compilation can never finish.
For the avoidance of doubt, C++ compilers may have an arbitrary internal limit on recursion depth, and exceeding that causes the compiler to give up in disgust. That means that C++ compiler cannot compile a valid conforming program.
The code,and explanations, can easily be found by searching.
Corollary: if the C++ designers don’t understand what they have created, what chance do mere mortals have of understanding?
If you don’t/can’t understand your tool, what is the probability that your code contains unrecognised errors.
No, unit testing cannot find such errors. If you think it can, then please supply a unit test that proves a transaction has ACID properties :)
Corollary: If someone is doing Template Metaprogramming, they need psychiatric help. Or 1000 hours of community service – debugging Template Metaprogramming. :-)
Really I admire the hack, but people… PLEASE do not let that stuff escape into the wild.
This is not unique to C++ – any language could have a similar problem with a program constructed to be undecidedable.
Which language(s) do have the problem with valid conforming programs?
Did those languages designers also refuse to believe the problem until someone rubbed their noses in it so they couldn’t deny it any longer?
The template system is Turing complete, so yes you have a Turing machine available to you at compile time, and yes that means you can implement infinite loops. It’s that simple. Any sufficiently complex system will exhibit this behavior. I haven’t seen it demonstrated, but I’d bet this week’s paycheck the C preprocessor could be made to do the same.
Template meta programming is a neat trick, but it’s going to get noticed in code review. It’s not going to escape into the wild accidentally. Either you have a really good reason for doing it and everyone understands that, or you are going to be rightly smacked upside the head for trying to commit it.
It’s also not a big deal. Any real compilation pipeline is going to have a timeout built in somewhere, or at worst an impatient human that will eventually mash ctrl-C and figure out what the heck is going on. An infinite loop in compilation is basically as good as a syntax error.
How can the C preprocessor be turing complete if it doesn’t have loops?
Turing completeness doesn’t require “loops”, it requires the ability to execute its program as its program requires. In this case probably by recursion, but you can make up your own imaginary Turing machine with its own weird but technically Turing complete language. Many other people have done so, I had an interesting example used as part of an interview several years ago.
This is such a strange issue to take – many “valid conforming programs” never terminate. Sure, it would be nice to get a compiler warning I suppose but your problem seems to be that the C++ compiler doesn’t solve the halting problem (which is not really what it’s there for…)
Not a C++ guru, but I heard there is still no buffer overfow detection implemented inside the compilers… /s
There is no bounds checking for array indices, but there are other containers like std::vector that do.
So? Learn to program correctly. Yes bounds checking exists on certain things today because people don’t know how to code. However this just slows things down and take up more space. If I allocate 10 bytes and I know that I only store 10 bytes and only ever read 10 bytes I don’t need some artificially constructed container because I am not a baby. An artificially constructed container is going to check every read and every write, a process that will take many instructions cycles, it is going to need to store a length somewhere taking up more space (probably 4 bytes), all to hold the hand of someone who should program in a language that is more hand holding. I am horrified by the complexity of ‘modern’ C++, it seems to include every idea from everything else ever invented instead of just letting people learn to be adults. This is the problem not just in C++ but in every piece of modern life.
You obviously haven’t been asked to do print 1 to 10 with a lambda in an interview. A lot of us make a living writing overly-complex C++.
I spent many years dealing with security bugs in products. A very large number of those bugs were introduced by people who sounded just like you.
Can’t recommend hire.
The grand majority of bugs and security holes are created when programmers say to themselves “that’ll never happen…” (or are too lazy/hurried/inexperienced to know or look up what can happen).
And there is your first bug: the length will potentially (likely?) be eight bytes (64 bits).
Sorry, had to do it. I’ve graded too many assignments to let that one get by. Done it myself a few times, it’s cool. :-) :-)
Anyway, if you really, really need to use C/C++ that way, you probably need to use machine language instead. Admittedly, x86_64’s 4000+ opcodes poses a challenge these days, but if you’re charging by the hour you’re golden.
Seriously, Intel – Gaussian Field instructions? Who on God’s Green Earth did you put that in there for? Never mind, I know who.
What you are describing is premature optimization.
People make mistakes, especially when you have someone that didn’t write the code changing it five years down the line with an angry customer or project manager breathing down their necks. You have zero control over who will change a code base next. It’s ALWAYS best to code defensively.
If you have an identified performance issue or hot spot in the code, then and only then does it make sense to “remove the brakes to save weight” so to speak. Those situations do occur, and you carefully comment them, spend more time analyzing them, increase test density, etc.
99.9% of code doesn’t run under conditions where those extra CPU cycles matter. Even in modern embedded systems you rarely have a processor that is near 100% utilization most of the time.
Optimizing to save every last CPU cycle by default is, frankly, a mark of immaturity. Part of being a professional developer is understanding when that behavior is necessary, and showing the discipline to mitigate risk when it is not.
I am working fulltime with c++ but have an embedded c background. If you are using c++20, sonarlint, clang tidy, wall, werror, etc, you will be fine :) using modern c++ you can avoid using pointers and direct accessing elements by index and other error prone practices. The c++ i write today is not the same language i learned 10 years ago. Regarding Rust, i would prefere a standard and more then one compiler, i doubt rust code written today will work in 5 years.
This!
Todays C++ is just as modern as Rust and have all the needed features to make memory safe and quality software with C++.
And you don’t even need to try hard..
Not even close. Safe Rust makes data races impossible.
And the moment you need to deal with real world, the safety goes out of the window because the OS libraries aren’t safe. Plus never mind that data races are only one type of problem – and not even the worst one you could encounter.
This superiority complex of Rust developers while being totally blind to very real problems that don’t go away only because one has switched languages is incredibly tiring already.
Rust from 2015 still compiles. I already have Rust code more than 5 years old.
And all those things add heaps more instructions and storage to your program, just so people can be lazy and not check or learn. It’s not as if the tools to help don’t exist today. Pointers and direct access are how the processor deals with memory, anything else is hundreds of extra it’s of code,just because it is hidden behind a name doesn’t mean it isn’t extra
We are also fallible humans. People don’t have to be just lazy or ignorant.
Human coders are fallible, and those faults include laziness. Unless they’re replaced by infallible AI (which seems highly unlikely), the languages they use need to accommodate reality. When critical software fails, or is compromised, saying “they were lazy!”, might feel good, but it doesn’t fix anything.
At some point, maybe it will the AI’s on here arguing their superior methods of generating code.
It’s hundreds of extra instructions, not hundreds of extra “lines of code”. Those are two very different things.
The former is usually being generated by well tested and mature container libraries that have thousands of people using them.
The latter is usually unique to a single product, application, or domain specific library with far fewer eyeballs on it. Every line of code is an opportunity for you (or more likely the intern that gets assigned to make a “trivial” change two years from now) to make a mistake. They carry very different levels of risk.
The extra instructions do represent increased memory and CPU usage, and those are at times scarce resources. Usually though a CPU spends the vast majority of its time in a tiny percentage of the codebase. Most lines of source code are there to handle errors, rare edge cases, and initialization that might occur once or twice during the execution of the program. Most real world applications tend to be I/O bound as well.
The tradeoff between performance and risk is not uniform across a codebase, and the places where “performance” is the more important consideration are the exception, not the rule.
“We are probably some of the worst offenders. It often seems like we use C++ the way we learned it several decades ago and don’t readily adopt new features like auto variables and overly fancy containers and templates.” thus makes me feel so much better. Often times new languages come in with new features and so much, but the C++ today is barely how I remember it. I ha e nothing against new languages but it doesn’t give me the power I have with c++, the nice feelings. Every other one makes me feel like I’ve reached into a new domain. But c++ always left me in wonder.
To be honest, lot of us doesn’t want to get it and we don’t have to get it. We need only some advanced features over C like namespace or minimalist objects which have minimal to zero runtime/size overhead compared to C code.
The problem with C++ is the legacy stuff that should never be used is enormous. Then there’s the endless list of weird features that should only be used in rare conditions. C++ needs guardrails and a reduced syntax. Rust provides that.
Sutter’s Cpp2 is an attempt at that, but I’m not holding my breath about it ever becoming mainstream.
Rust has the same problem in that it’s also evolving and growing, and at a much faster pace than C++ ever could since there’s no ISO committee to drag things down. The editions are supposed to mitigate that somewhat, but you still have the same problem of having to unlearn old practices, and encountering legacy code.
A lot of programmers who learned the syntax of C++ skipped learning how to do object oriented design and programming let alone nee C++ features.
I wish I could find my old presentation I used to give for a NASA contractor back in the 1990s called “12 words to object oriented programming.” It was to combat exactly what you are talking about.
I’d probably read that.
Cpp was a mistake in 1990, 2005 and it’s still a mistake in 2025.
At work I use a MISRA-like subset of C that’s super limited in terms of features but it get the job done just as good as C++, Java or C# would do, except it doesn’t leak memory or waste CPU cycles.
If C++ is the answer, then you need to go back and re-assess the question. :(
Sure, the (other) people commenting here might[1] write perfect code, but what about all the libraries that they use?
[1] remember the C++ committee who didn’t understand what they had wrought!
I describe MISRA as “the parts of C that are also in FORTRAN 66”. I mean that as a compliment. If it isn’t true, it’s mighty close.
“You can write Fortran in any language.’
c++ software obfuscation?
Is c++ implemented with certified software modules?
AI Overview
“Certified software” refers to software that has been independently evaluated
and verified by a recognized organization to meet specific quality standards,
often related to security, functionality, performance, or reliability,
signifying that it has passed rigorous testing and meets certain criteria
for its intended use; essentially, it’s a label indicating a level of assurance
regarding the software’s capabilities and compliance with industry standards.
Bjarne? Bjarne? If you don’t want people to subscript pointers, then why is that in your language, Bjarne?
Probably since there are times you need to. That is the beauty of c/c++ . The do anything language, where you are not bound by the language. Your free to do anything. Wonderful. Unlike Rust, where the ‘compiler’ kicks back at every turn even to point of how you format your code statements…. embedded/real-time C programmer since ’85, with some C++ over the years. And Turbo/Delpi Pascal as well. C with ‘some/basic’ Oop works well. Using the obscure features of C++ sucks for maintainers down the road though. KISS. Experienced this as a maintainer of a previous engineer. No fun to figure out what is going on when you have to dig to make a change.
Here is too another 45 years!
Subscripting pointers is possible because it was easy to do on a PDP11. See K&R first edition.
I like it when a compiler complains at compile time – because that prevents some avoidable problems occurring at runtime 3 years after the perpetrator left the company. No, it doesn’t prevent all problems, but it reduces frequency with which they occur.
Here’s to another 45 years of COBOL!
(Damn; escaped too soon)
“because” is because it was easy for the compiler to do, and because the PDP11’s instruction set implemented it efficiently.
Fundamentally, it is a “leg of lamb”/”pot roast” feature https://www.psychologytoday.com/au/blog/thinking-makes-it-so/201402/the-pot-roast-principle
I have used C++ forever. I have not adopted some new styles because I have an existing code base of tools. I think the problem with committee design is the introduction of regressions in existing code, they simply do not back-test when they deprecate or change things.
It seems to me the reason some of us still use C++ like “C with optional objects” is because that’s how it started out. The first two versions of “cfront”, the original C++ compiler, didn’t emit assembly code, they emitted C, which was them compiled to assembly and assembled. Thus, all the semantics of early C++ have a 1:1 mapping to a fragment of C. There’s is no reason in the world for me to know that a “vtable” exists, what it does, or why it’s there. The problem is, I DO know. I HAD to know, because the debuggers didn’t catch up to the language for nearly a freakin’ decade. And I’ll just throw this out there: Name Mangling. You’re welcome.
Remember the treadworn advice “don’t use templates, they’ll break the debugger!”? Break the daylights out of it. Wound up having to put a printf() everywhere (sorry, “cout”) just so you could tell which method (sorry, “member function”) you were in.
Lately I’ve been writing Erlang at work. If you don’t like C++, Erlang is as different as conceivably possible. When I stand up after a while, I have to try to remember where I am.
“It seems to me the reason some of us still use C++ like “C with optional objects…”
The way it ‘SHOULD’ be. There is absolutely no reason to use objects just because. You should have a very ‘good’ reason to do so. Use where it makes sense. Even in python, I won’t create ‘objects’ — just because the construct is available. Code is usually much cleaner this way, rather than hiding the code behind objects for no reason. Don’t get me wrong. Sometimes objects make sense to use. Just don’t use them for the heck of it. One of biggest ‘headaches’ at work is a previous engineer using c++, objectized everything because he could and used overrides on operators. Ugggh. So tracing down the code (object) chain, you’d forget what you were looking for by the time you reached bottom and have to start over again. Very obtuse. After addressing what you are looking for, a couple months go by and guess what… Have to do it all over again…
Always disliked the name mangling too when debugging. One of the reasons I still prefer to write in straight ‘C’. Simple and straight forward coding. Easy to follow the assembly in the debugger.
Name mangling is ugly, an indication that the tool is becoming part of the problem rather than part of the solution.
Operator overloading makes some simple things pretty. When (mis)used on more complex things, it rapidly makes them incomprehensible.
Another example of C++ including things because they appear k3wl, not because they are beneficial.
Did COBOL fall into that trap?
I never liked C++, the standard template library was always no more than a bag on the side. While I had to use C itself for a couple of decades, for the last few years of my career I ended up using C# which was so much better than C++ in all ways – no multiple inheritance, generic classes that were type safe even with user defined classes by the use of interfaces, etc. Rust wasn’t even a gleam in the designer’s eye but I suspect it is superior to C++ in every conceivable way. Languages come and languages go, but C++ has proved to be generally write only code that never deserved any prominence in the first place.
Of course, that is just my opinion, but had C++ been a necessity I would simply have found a new job – maintaining other people’s C++ was more than enough for me, it was a relief to retire and leave that chore to others.
Problem I had was C# is a M$ .net centric (with all its baggage) language. Not built for cross platform like Java or even c/c++. I only wrote one application with C# and truthfully, I didn’t mind it at all. Easy to use. Just didn’t fit with the projects I work(ed) on so never went any further. Yes you can write some C# on Linux now if needed although GUIs are (or were) limiting, but between C/C++, Pascal, Java, Assembly, and Python … I’ve got a mind full of syntax to keep track of! You don’t find C# on micro controllers, RPIs, etc. either. I’ve got a friend in IT which loves it. But he gets frustrated when trying to use it for home hobby projects and usually ends up with Python as the goto language which he is finding is a better fit.
To me, C++ was always a rushed and “just good enough” solution. It’s clunky all over, from the way it does vtables, spaghetti includes and the ugliest operator overloading. The steam printing is outright criminal, more of demo showcase for operator overloading, that just lingered and made it into the text books, yuck. Namespaces seemed an attempt to address some of the ugly, but just made it even uglier.
Worst of all it was the start of “self documenting” APIs. Before you would get MSDN article and an API documentation written by a technical writer. With C++ you got the auto generated documentation based on a class structure, cheap!
OOP sucks and C++ is largely to blame for OOP’s market acceptance and growth so I blame it for that too.
Cue the OOP sycophants wailing and gnashing of teeth about why I’m wrong.
I like C++ I found it for the first time alongside Arduino Uno. It does the job tho. And it invites me to think in a clear manner, I hate Python but I use it to code trading bots, so it is fine, I hate android and all the apk stuff… but I’m not an expert so i can’t tell which language is good or not.
voodoo! voodoo i say!
continues using c++ as the ancients intended
Semicolon bother!
Semicolon!
Can I get a semicolon from the congregation?
I’ve been using c++ for much of that 45 years, and still like it. I have recently done some server stuff in rust – it has it’s good points and bad point (as any language). The two biggest bad points are –
– anything connected to hardware has to be ‘unsafe’ fairly quickly, thus removing some of the rust benefit.
– it isn’t OOP. I’ve noticed younger programmers who have been using it all their life don’t find that a problem – however the whole trait system, which works well if done properly (like writing c++ properly) rapidly turns un maintainable mess if done badly (like C++). And the bigger it gets, the harder to do it right (even more so than c++).
I, who have been programming daily for many decades, find rust to be great and horrible at the same time. It is extremely frustrating to get things structured right, and compiled, but then they tend to work…
The missed opportunity is a shame, if they had made rust OO, and left much of the rest of it, it may have finally been a replacement for C++…