DEV Community

In Defense of C++

Dayvster 🌊 on September 10, 2025

The Reputation of C++ C++ has often and frequently been criticized for its complexity, steep learning curve, and most of all for its abi...
Collapse
 
dyfet profile image
David Sugar

While C++ is complex, it is also often effectively expressive of that complexity. For some things I have also found it better to go back to pure C. There are things I love about go, too. But Rust would now be my very last choice for programming.

Collapse
 
dayvster profile image
Dayvster 🌊

This is why I try to adhere to the just write C++ as if you were writing C until you need some of it's more complex features.

you can get really far with just imitating C in C++

Rust on the other hand for me is the opposite of that, you start with complexity right out of the gate.

Collapse
 
olvap profile image
Pavlo Mur • Edited

Pure C is perfect unless one starts to invent own "OOP in C", own "inheritance" like stuff around... And everyone "reinvents" this in their own custom way:

Some teams/projects/libraries place function pointers directly into data structures, others maintain separate "VMT-like" stuff manually... Some cast pointers back and forth, some use ugly Base_Method(&objPtr->base.base.base) approach, some write inline wrappers in every header for every "derived" class to call base's "methods"...

...and all that stuff is done and tracked manually including calling of "destructors" and ultimately "everyone must be very careful to track the life time manually" (some even use AddRef/Release like API imitating "smart pointers", but this is still manually maintained boilerplate hell)...
This all is mixed with all workarounds and implicit conventions that are in many cases not written in any docs at all (!) and one must figure out this by literally "reverse engineering" the code. But even if rules are written, still everyone tries to "shortcut" and skip some rules by inverting own undocumented "algebraic types" as "tagged unions" with own implicit conventions and special ownership rules...

Clearly even C++ classes are much better instead of all those custom "inventions" of "OOP in C". Also std::variant is much better than all those manually maintained "tagged unions" as custom "algebraic types"!

Who owns what? When I shall free that resource? Etc... (if there are no destructors "by design" there shall be at least "go-lang-like defer" supported by the language)... Yes C++ is not as perfect in all of this, as Rust, but still I can at least ban copy and assignment everywhere and enforce "rule of 5" instead of all those "be careful" and "watch your step" everywhere!...

Yep, C++ standard containers are far from being perfect,
but "pure C way" for manual linked list management (especially when one's data are members of multiple linked list chains simultaneously) while one manages casts from nodes to the whole data structures with a set of ugly macros, for the most of the real world projects this is just an overcomplication that makes project support kind of hell (unless ones name is Linus, but with adding Rust I think he is heading the right direction))

Collapse
 
dyfet profile image
David Sugar

Indeed the main reason I migrated from C to C++ in the 90's touched upon this. In the 80's I did a Ui toolkit, VU, which, like so many similar things at the time, of course was doing object oriented code in pure C. OOP in C is about an artificially enforced discipline and style since C does nothing to "enforce" correct use and practice. Obviously, that made C++ seem far more intuitive a choice. But there are also many things you can do in pure C, too, and sometimes do so much more efficiently without any abstraction or large runtime overhead.

Thread Thread
 
olvap profile image
Pavlo Mur

The niche for C is very close with "stripped out C++" (the so called "Arduino Scripting language" is actually C++, one can use even lambdas and templates, but no "iostreams" and no C++exceptions)).

Still, definitely any external binary API (exports) must be in C, to be perfectly interoperable practically with "anything" (not only because of name mangling in C++, but also because of binary layouts, that are broken, unless one follows "close to C" rules... exceptions also cannot cross module boundaries, etc... The only known binary interoperable C++ stuff looks to be COM from MS, that abuses the fact that VMT layout is the same for the selected platform)

Collapse
 
jodaut profile image
José David Ureña Torres

Great article! C++ is a very important language and is widely used actually. As you mentioned, it does not compete with Java, Python or JavaScript. The all serve to different areas of software. C++ is great for Linux/Unix programming for example, or systems where memory management and speed are crucial. Or when you need very small executables. Java and Python cannot offer that xD.

Collapse
 
andrescass profile image
Andres Cassagnes

That's the whole point. I always say to my junior coworkers, there are no better or worse languages, there are languages better for specific uses.
There is no language that fits perfectly in all the circumstances

Collapse
 
dayvster profile image
Dayvster 🌊

it's still the language that holds up the most important infrastructure and projects well C++ and C.

It's gonna take a while for any language to replace that, Zig might.

I don't know if Rust can it's nice and all but binaries that are 3-5x the size and often slower just don't seem like the way forward to me.

Collapse
 
jlburgos profile image
Juan Burgos • Edited

C++ is only complex in the variety of ways you can solve any arbitrary programming problem. If you only use the tools and language constructs that you actually need, then the language is only as complex as you need it to be. This isn't even specific to C++. Every other language that has existed for decades has "issues" the people tend to complain about. Only reason newer languages are sometimes considered safer is that they stand on the shoulders of giants, have carved out a specific niche instead of being a generalist language, or hide so many details of the underlying behavior (looking at you python) that memory management is likely not your primary concern.

Ultimately, the best antidote to fear and confusion, especially when it comes to learning "difficult" languages like C++, is as follows:

  • Patience when learning the language and the tool-ecosystem.
  • Mindfully using only those language constructs that you actually need.
  • Less dogma about what is considered arbitrarily "better" or "safer".
Collapse
 
dayvster profile image
Dayvster 🌊

Precisely!

Well put, this is basically one of the points I tried making in the article but you articulated it quite well here.

Thank you :)

Collapse
 
optimisedu profile image
optimisedu

This is a brilliant article your voice and points ring very clearly and brings up the sad facts that we are getting a huge amount of content the is at least partially ran through a neural net giving it the same homogenised voice I have to apologise for my lack of punctuation and hope this makes sense I'm currently time looking for a new Hobby and I think I have matured into being ready to learn C++ from the ground up again a first try learning C++ in 1996 I was five years old and using a textbook eventually became a pretty bad program using basic an eventually SEO got me into performance optimisations for business again however since JavaScript is where my market was I specialised in scripts than a compiled language with pointers and other such low level functionality I have a broken hand and a lot of time to kill any suggestions on a good place to learn C++ from the Ground Up would be really appreciated just extremely frustratingly slow.
great article truly

Collapse
 
dayvster profile image
Dayvster 🌊

thanks, that's a huge compliment, appreciate it.

Collapse
 
teminian profile image
Robert Teminian

Bravo. As a C++ developer myself I can't agree with you more.

Collapse
 
dayvster profile image
Dayvster 🌊

Appreciate it!

Just for my curiosity how many years experience would you say you have with C++ ?

Collapse
 
teminian profile image
Robert Teminian

For professional use, it's been 5~6 years.
But, if I include my "prelude period", I'd say "have you ever tried Turbo C 2.0 with 5.25 inch floppy diskette?"

Thread Thread
 
dayvster profile image
Dayvster 🌊

Hahah fair, thank you.

I'm putting together another blog post in the near future, I've noticed an interesting trend in how people with different experience levels responded to this particular post. Think it might be worth a deeper dive

Thread Thread
 
teminian profile image
Robert Teminian

Sounds fun! I look forward to seeing your followup post.

Collapse
 
dimonic profile image
dimonic

I was nodding to most of the things you were saying, until you got to boost. Boost is not bloated at all - in nearly all cases, it is only headers - no binaries at all. It is also under constant ongoing development, and not "out of date" at all. Time after time, its best features get adopted as part of either the language standard, or the standard library - including those smart pointers you raved about.

Please take some time to research boost before you malign it.

The one criticism I would say is fair is that its documentation seems opaque at first.

Collapse
 
dayvster profile image
Dayvster 🌊

I do a lot of embedded or embedded-like programming where boosts overhead does not lend itself well to the use case.

So naturally I do not like boost.

Boost to me fits this strange use-case. So basically boost usually comes into play when you are developing desktop applications and web applications, which is fine.

How do I explain this without sounding like an asshat.

I think boost allows developers to create software where C# and Java would be a solid choice as well at which point why not just go for C# or Java?

But I do appreciate your feedback, do not feel slighted by my personal distaste for boost, I don't look down on people who do use it nor should anyone.

Collapse
 
dimonic profile image
dimonic

I write primarily embedded software (for ground penetrating radar). I also create high performance C++ libraries for signal processing for consumption by python for physicists to use (using the boost-python wrappers). I use the same core code on three different platforms (embedded arm, cloud and desktop).

I have measured many use cases for boost over the years, and have found zero cases where boost makes the code significantly larger than any alternative I could find. That is not to say it could not happen, but I have used dozens of boost "libraries" (mostly, as I said, template headers) and not seen the problems you described. I would hate to accuse anyone, but I have found the so called bloat problem to be a myth.

Thread Thread
 
dayvster profile image
Dayvster 🌊

It's not exactly a myth.

Here's the thing, you can absolutely import individual boost libraries and keep the impact on the binary size fairly minimal. But it will still be enough of an impact where it will be very hard to excuse using it if you want your entire binary to fit on a device that has somewhere between 64Kb to a max of 8Mb of Flash.

and the 8MB Flash ROM, most consumer grade vehicles will have MCUs with about 128-512KB of Flash.

There is no C++ boost library that will lend itself to this. Or rather very few, and their capabilities are fairly limited and trivial to write on your own.

So my perspective on boost is heavily colored by this, now if your experience is using boost for desktop applications, network programming etc. etc. that's a different story, I can see why you'd like boost in that case.

Collapse
 
eagerm profile image
Michael Eager

The advice to developers, especially ones new to C++, to write in a constrained subset of C++ is one which I have offered many times in the past. But while you can write C programs, using the C library functions like printf() or your own linked lists functions, why compile them as C++ instead of C? There's little benefit in pretending that a C program is C++.

Constraining the C++ features which you use may reduce the complexity of your particular program, but it does not reduce the complexity of the C++ language. There are a few caveats with this advice.

First, the inherent complexity of C++ cannot be easily hidden. As soon as you use any features not in C, such as streams, STL containers, classes, etc., that complexity is incorporated into your program. Because the various functional features of C++ are not independent, generally using any C++ feature brings in all of C++ complexity. This results in cryptic error messages and hidden operations.

Second, this advice only applies to new single-developer programs. I think that few people have that luxury. I work with C++ programs with hundreds of files and hundreds of thousands of lines of code, developed by tens to hundreds of people over the space of decades. While I can limit the C++ features I use when I add code, I can't control what other developers have done in the past. If they have used multiple inheritance, questionable operator overloading, or friend classes liberally, I might think that this is bad form, but if I want to fix a bug or add functionality, I have to understand these features.

C is a small language, easy to understand in its entirety, with few dark corners. What you see is what you get. C++ is a large language, with many areas which are complex and not easy to understand. Often, what you see gives little clue about what is happening out of sight. Here are some examples.

If I see the statement
Foo bargle;
in a C program, I know that Foo must be a type and bargle is either data or possibly the declaration of a function named bargle(). There's no code executed, except perhaps to reserve some stack space depending on where this statement appears. In C++, this may or may not create an object in memory, it could declare a function, and, if Foo is a class, may execute a constructor which has unbounded complexity. If this statement appears outside of a function, then this constructor runs before the program starts at main().

[I work on a program where creation of sub-processes and the setup of communication between these process is all done "magically" in constructors for global objects before the program starts at main().]

If I see this statement
razzle(99);
in C, I can assume that razzle is a function and it is being called with an integer argument. In C++, razzle might be a function, it might be a scalar type (such as int) which is being set to 99, or it might be constructor for a class, executing whatever code is in the constructor. (Incidentally, distinguishing between the multiple possible meanings of this kind of statement makes parsing C++ a challenge.)

While setjmp/longjmp is a horror, in C longjmp() does exactly two things: it resets the stack pointer to the saved value and continues after the setjmp() call. It's your responsibility for any needed cleanup. Exceptions in C++ are a huge improvement, but when a throw statement is executed, there is a large amount of hidden processing to walk the stack and do cleanup in each function which needs it. This is a very complex process, one which is hidden from sight.

C++ is a complex language which takes a long time for someone to be proficient with. It's not easy to create a functional subset (there was an effort to create Embedded C++ years ago, essentially "C with Classes" as C++ was originally designed). My recommendation for new programmers is that C++ is a good second language, after one has learned the basics of problem decomposition, program design, data structures, and other concepts.

Collapse
 
josephdailey11 profile image
JDailey

I took a year of programming language and choose C++ over Java; however, I found my i5 machine in windows was getting in the way. I didn't finish, but I think my love for Linux will bring be back on my own. I think programming is hard, but if you look at it all if else statements are similar. I thought it was easier than BASIC in the 80's to be honest.

Collapse
 
sephyi profile image
Sephyi

One thing I’ve never understood about C++ is why so many projects still stick to outdated versions of the language. I’ve seen projects started only a few years ago that were already locked to something like C++11 (from 2013). Am I missing something here? I’d really appreciate some insight, because I honestly don’t get it. Or maybe I’ve just had bad luck and this isn’t how things usually are in the broader C++ world.

I’ve worked with C++ already myself, but at this point I wouldn’t recommend it to anyone unless they have a very specific, unavoidable reason. If someone already has solid experience in C or C++, that’s different. But for newcomers, I don’t see a single strong argument in its favor—only a long list of potential pitfalls, ranging from mildly annoying to seriously painful.

Collapse
 
elanatframework profile image
Elanat Framework

C++ is hard to use on the web. I couldn't find any C++ web frameworks to test the C++ WebForms class.

C++ was the first programming language I learned in college, although I later learned programming at a reasonable level by reading a useful book on the BASIC programming language.

Collapse
 
andrescass profile image
Andres Cassagnes

C was my first programming language, but C++ is the language of my heart.
I work in safety, critical systems and there is no competitor to C/C++ in those areas.
Also in one of the leader measurement instrumentation systems, the language is C++.
Moreover, is a really beautiful and elegant language if you put the effort to write the code.

Great article, very good points, that I will take and use in my future discussions about programming languages.

Collapse
 
jeffsilverm profile image
Jeff Silverman

Why do you think poorly of Ada for safety critical systems?

Collapse
 
csm18 profile image
csm

The first oop lang I encountered was C++.I like the lang.
But, feel overwhelmed to use the build systems.
Do you have any suggestions on it?

Collapse
 
dayvster profile image
Dayvster 🌊

the build system is arguably the biggest weakness of C++

Sadly we are mostly stuck with Ninja / CMake for the foreseeable future.

Collapse
 
aregtech profile image
Artak Avetyan

I would say that not the C++ language is complex, but the frameworks we use bring complexity. The language is very flexible and that's why I love it.

Collapse
 
dayvster profile image
Dayvster 🌊

Eeeh it can spiral out of control pretty fast if you try to use too many of C++'s features.

But that's the secret, you don't need to you should just write it as C until you need more complexity.

Collapse
 
prime_1 profile image
Roshan Sharma

I like how you point out it’s still evolving (modules, coroutines, etc.) and that complexity doesn’t always mean bad.

Collapse
 
dayvster profile image
Dayvster 🌊

Appreciate it, thank you.

People love to bring up this point against C++ and even C that they are old. Even though they have been receiving a lot of updates and new features fairly regularly.

Collapse
 
parag_nandy_roy profile image
Parag Nandy Roy

C++ isn’t perfect..but it’s battle-tested and still powering some of the coolest stuff out there...

Collapse
 
prime_1 profile image
Roshan Sharma

Totally agree, C++ doesn’t have to be super complicated. Stick to what you need, and it’s still super powerful and flexible for real projects.

Collapse
 
pistolario profile image
Marcos Pérez

New versions of C++ add complexity and, at the same time, add safe memory features, so, you have to choose what kind of C++ you want to keep.

Collapse
 
highlightsai profile image
Highlights.ai

good job!

Collapse
 
dayvster profile image
Dayvster 🌊

aww, thanks!

Collapse
 
pauljlucas profile image
Paul J. Lucas

This is mistagged: it should be tagged #cpp. #c is for C.

Collapse
 
eslamlinux profile image
eslam linux • Edited

😎👌🔥
In fact, despite the complexities and some of the challenges I face, I enjoy writing code in this wonderful language. No, it has not been rendered obsolete by time; even after 40 years, it is still considered a powerful and sustainable language.