This is prompted by a an answer I gave to a current question which asks about a generics library for C - the questioner specifically states that they do not want to use C++. My question to him and others who insist on using C is why do they do so when:

  • C++ provides the specific features they are asking about
  • Their C compiler is almost certainly really a C++ compiler, so there are no software cost implications
  • C++ is just as portable as C
  • C++ code can be just as efficient as C (or more so, or less so)

Please note: This is not intended to be argumentative - I am genuinely interested in the motivations for the choice of language.

Edit: It has been suggested that this is a duplicate, but I don't think it is. To clarify, I'm interested in why people limit themselves to the C subset. For example, the questioner in the post I referred to could have kept all his old C code and just used C++ generic containers as "better arrays" - I am interested in why are people so resistant to this? I am not interested in why you should or should not learn C or C++.

Peter Kirkham's post was for me the most informative, particularly with regard to C99 issues which I hadn't considered, so I've accepted it. Thanks to all others who took part.

+16  A: 

I hate programming in C++.

Lol I like that one
Very convincing! I'm thinking of switching to Python based on your argument.
Jimmy J
Maybe not convincing, but it's the true reason.
I'm with you on this.
+5  A: 

Windows kernel development doesn't support c++ (sadly).

How is that? Why? Is the binary produced from a C++ compiler different from a C compiler? Isn't driver development simply adhering to API's?
Dave Van den Eynde
Because a lot of C++ features require runtime support which may not be trivial to implement in kernel-mode. For one thing, different memory allocation functions are used, so chunks of the standard library would have to be replaced. Exceptions are generally bad too.
+4  A: 

You can read an entertaining rant about why Linus Torvalds favours C here

Paul Dixon
It's more of a half-coherent rant against object-oriented design than a rant against C++.
Dan Olson
...and if you study the LKML FAQ regarding C++, you will notice it's more about xenophobia than about facts.
Mr Torvalds has a long list of things he doesn't like, C++, emacs, Subversion, OO to mention a few. One sometimes wishes he would button his lip a little more
Linus likes to rant and try to provoke and upset people. Unfortunately, he hasn't bothered to *learn* C++ before declaring that it sucks. Unfortunately, his cult following believe that everything he says must be true.
The link was more for entertainment than education
Paul Dixon
Proof that even geniuses can sometimes be dolts.
Kaz Dragon
The half-coherent rant is a Linus trademark...
Norman Ramsey
You have to understand the space Linus lives. Anyone who has not done kernel programming does not understand the constraints involved.
Can't argue with someone who starts his posting with "*YOU* are full of bullshit." :)
Michael Stum
Linus built his kernel in C because that's how unix kernels are built. Linus' way of designing kernels and the C++ version of OOP are non-mixable. Name one Operating System Kernel written in pure C++ without any ANSI C modules? Okay. I think it's hilarious that his argument against OOP is that it makes it harder for him to use grep "long_function_name_here".
Warren P
+13  A: 

I do not see any reason other then personal dislike, even for programming embedded systems and similar things. In C++ you pay overhead only for features you use. You can use the C subset of the C++ in some specific situations where C++ overhead is too high for you. This said, I think some C programmers overestimate the overhead of some C++ constructs. Let me list some examples:

  • Classes and member functions have zero overhead compared to normal functions (unless you use virtual functions, in which case there is no overhead compared to using functions pointers)
  • Templates have very little overhead (most often no overhead at all)

One valid reason would be when you are programming for a platform which does not have a decent C++ compiler (no C++ compiler at all, or a compiler exists, but is poorly implemented and imposes an unnecessary high overhead for some C++ features).

A class with virtual functions has more overhead: each instance has to carry around an extra field to identify the type.
More overhead than what? The type is carried in the vtbl. If you implement similar mechanism using function pointers, you need at least one pointer (or index, or whatever) to select the function pointer you want to be used.
bstpierre: I think what Suma is saying is: that it has no more overhead than implementing the feature manually yourself in C.
Martin York
A pointer to the classes vtable is stored in each instance of the class.
There is an overhead, but what I mean is that if you want any dynamic type resolution, you need some storage to identify the type, even in C. If you do not want the dynamic types, you do not need to pay the overhead (do not use virtual functions if you do not need them).
This virtual function thing is a total sidetrack. The claim in Suma's post is that "you pay overhead only for features you use". If you don't use virtual functions, you don't pay the overhead. If you can't live with the overhead, don't use them.
Jason Orendorff
Exceptions are also more costly than simple returns. This may matter in some embedded situations. Also binary size and runtime may be critical.
Amigable Clark Kant
Again - you are not forced to use exception in C++. You can stay with return values. (I am a game developer and we never use exception handling in our games, as the performance cost of it is too high for us)
+3  A: 

If you work in an environment with two languages, you might use C for some performance critical low-level functions and a more functional/high level language like C#/Java for the business logic. If C++ code is usedfor these functions ,C-Wrappers are required for JNI/unmanaged code around and this makes things more complex than solely using C.

+6  A: 

I've never seen any arguments for using C over C++ that I'd consider convincing. I think most people are afraid of certain features C++ offers, often justifiably. Yet this doesn't convince me because one can enforce whether or not to use certain features through coding standards. Even in C, there's much you'd want to avoid. Discarding C++ entirely is essentially saying it offers no tangible benefits over C that would help one write better code, which is a view I consider to be quite ignorant.

Additionally, people always seem to raise the situation of platforms where no C++ compiler exists. Certainly C would be appropriate here, but I think you'd be hard pressed to find a platform like that these days.

Dan Olson
Agreed, the "C is better than C++" rants never stand up to scrutiny.
Jimmy J
I believe C++ offers me VERY LITTLE benefit, and COSTS ME a huge amount of accidental complexity. I believe it would take about 1500 pages of C++ textbooks, and ten years of effort, to become as proficient in C++ as I currently am in C, Pascal, Python, and Objective-C. Each of the above languages is about 20x more orthogonal, compact, and mentally convenient to use, not to mention more powerful, in the environments where I use them. There are simply NO rationally justifiable uses for C++ in my usual development environments.
Warren P
@Warren You only pay for what you use, just like any language. If you're not capable of deciding how to code wisely in C++ that's on you, not the language.
Dan Olson
Not so. If you are the only developer on a project, that might be so. But as soon as we have two developers, we have battles. What? You insist on IoC containers, whereas I prefer some other way of doing delegates... You like three levels of nested templates, and I prefer zero templates. A mess.
Warren P
+34  A: 

C++ simply isn't supported in some real-world environments, like low-level embedded systems. And there's a good reason for that: C easily good enough for such things, so why use something bigger?

Joonas Pulakka
Right. I've seen c compilers for 8 bit micro controllers.
of course. Most if not all 8-bit chips have C compilers these days.
Eli Bendersky
http://gbdk.sourceforge.net/ - GBDK for one..
Kelden Cowan
+1 this is the correct answer. C++ compilers are much harder to write than C compilers, largely due to the complexities of (multiple-)inheritance.
BlueRaja - Danny Pflughoeft
@BlueRaja: compared to templates... multiple-inheritance might not be the real deterrent here. After all templates constitute a fully-fledged language of their own.
Matthieu M.
+6  A: 

C++ has a much longer learning curve. C has only few constructs you need to be aware of and then you can start coding powerful software. In C++ you need to learn the C base, then the OO and generic programming, exception, etc. And after a time you may know most of the features and you porbably can use them, but you still don't know how the compiler will translate them, what implicit overhead they have or not. This takes much time and energy.

For a professional project this argument may not count, because you can employ people that already know C++ very well. But in Open Source Projects, where C is still widley used, the people pick the language they like and they are able to use. Consider that not every OS-programmer is a professional programmer.

Erm... no? You learn the C base (possibly with the exception of arrays and C-style string handling dropped in favor of <vector> and <string>), and you get going. You can pick up everything else as you go along. You don't have to know anything about OO, GP, or exceptions to get started with C++...
C may be "smaller" but in the long term it isn't easier to use. Manual memory management? No thanks.
Jimmy J
There ain't no such thing as automatic memory management in C++.
Warren P
+1  A: 

Most programmers take it for granted that everyone considers quality a high priority. That's not always the case. If you're use to C, C++ might seem like it's doing too much for you behind the scenes. The strictness of type checking in C++ might also seem confining. Many people are willing to risk introducing the kinds of bugs that C++ can help prevent to avoid these "nuisances."

Rob deFriesse
Hmm, the reason I switched from C to C++ (a long time ago) was for the stricter type checking. I like having the compiler find my mistakes rather than the user experiencing a core dump.
+46  A: 

I realize it's neither a professional nor a particular good answer, but for me it's simply because I really like C. C is small and simple and I can fit the whole language in my brain, C++ to me has always seemed like a huge sprawling mess with all kinds of layers I have a hard time grokking. Due to this I find that whenever I write C++ I end up spending far more time debugging and banging my head against hard surfaces than when I code C. Again I realize that a lot of this is largely a result of my own 'ignorance'.

If I get to chose I'll write all the high level stuff like the interface and database interaction in python (or possibly C#) and all the stuff that has to be fast in C. To me that gives me the best of all worlds. Writing everything in C++ feels like getting the worst of all worlds.

edit I'd like to add that I think C with a few C++ features is largely a bad idea if you're going to be several people working on a project or if maintainability is priority. There will be disagreement as to what constitutes a 'a few' and which bits should be done in C and which bits in C++ leading eventually to a very schizophrenic codebase.

I used C++ for several years and still spent 50% of my time refactoring code to be "C++ correct". It's a nightmare, as you say.
You could always just do it right the first time. Adding const isn't difficult.
I used C++ for ten years, and going back to C (for embedded systems in my case) was the best thing I ever did.
Warren P
+22  A: 

A couple of reasons might be:

  • Lack of support - Not every C compiler is also a C++ compiler. Not all compilers are particularly compliant with the standard, even if they claim to support C++. And some C++ compilers generate hopelessly bloated and inefficient code. Some compilers have terrible implementations of the standard library. Kernel-mode development generally makes use of the C++ standard library impossible, as well as some language features. You can still write C++ code if you stick to the core of the language, but then it may be simpler to switch to C.
  • Familiarity. C++ is a complex language. It's easier to teach someone C than C++, and it's easier to find a good C programmer than a good C++ programmer. (keyword here is "good". There are plenty of C++ programmers, but most of them have not learned the language properly)
  • Learning curve - As above, teaching someone C++ is a huge task. If you're writing an app that has to be maintained by others in the future, and these others may not be C++ programmers, writing it in C makes it a lot easier to get to grips with.

I'd still prefer writing in C++ when I can get away with it, and overall, I think the benefits outweigh the disadvantages. But I can also see the argument for using C in some cases.

+17  A: 

There are loads of arguments about embedded programming, performance and stuff, I don't buy them. C++ easily compares to C in those areas. However:

Just recently after having programmed in C++ for over 15 years I've been rediscovering my C roots. I must say that while there are good features in C++ that makes life easier there are also a load of pitfalls and a kind of "there-is-always-a-better-way" of doing things. You never actually get quite happy about the solution you did. (Don't get me wrong, this could be a good thing, but mostly not).

C++ gives you infinite gunfire. Which could be arguably good but somehow you always end up using too much of it. This means that you are disguising your solutions with "nice" and "pretty" layers of abstractions, generality, etc.

What I discovered going back to C was that it was actually fun programming again. Having spent so much time modeling and thinking about how to best use inheritance I find that programming in C actually makes my source code smaller and more readable. This is of course depending on you level of self-discipline. But it is very easy to put too much abstractions on straight forward code, which is never actually needed.

No offense, but it might also depend on what you think C++ is. Inheritance is something I associate more with Java than C++, and if you treat C++ strictly as an OOP language á la Java (C with classes), then I agree with you. If you stick with a more modern flavor of C++, I think it's more fun than C
No offense taken; although I don't think of C++ as C with classes. Inheritance was just an example. It is a different language and should be treated as such. Nevertheless, I find C++ projects all too often containing unnecessary code just to follow some OO paradigm.
Once again though, I don't think of C++ as an OO language, and it shouldn't be treated as one. I think generic programming is a much stronger trait of C++. Most of the C++ code I see doesn't try particularly hard to be "OO", or contain unnecessary code. It's often leaner than the equivalent C code
In any case, +1 from me. It answers the OP's question, and I can see where you're coming from. I just think taking a different perspective on C++ would solve the problem as well :)
@jalf: Another thing that I find can become a "there-is-always-a-better-way" distraction in C++ is generalising things with templates. "Maybe we should let the user of this class decide what underlying integer type to use?" But you probably don't *need* that, and in C you wouldn't bother. And sometimes I find myself thinking, "We should really provide a forward iterator interface to this class," when in C you would just expose a pointer to the first element and a count, or (the height of fanciness!) a function taking a callback function pointer.
+7  A: 

I'd like to follow up on Dan Olson's answer. I believe that people fear the potentially dangerous and counter-productive features of C++, and justifiably so. But unlike what Dan says, I do not think that simply deciding on a coding standard is effective, for two reasons:

  1. Coding standards can be difficult to strictly enforce
  2. It can be very difficult to come up with a good one.

I think that the second reason here is much more important than the first, because deciding on a coding standard can easily become a political matter and be subject to revision later on. Consider the following simplified case:

  1. You're allowed to use stl containers, but not to use templates in any of your own code.
  2. People start complaining that they'd be more productive if they just were allowed to code this or that template class.
  3. Coding standard is revised to allow that.
  4. Slide a slope to an overly complicated coding standard that nobody follows and use of exactly the kind of dangerous code that the standard was supposed to prevent, combined with excess bureaucracy surrounding the standard.

(The alternative that the standard is not revised in step 3 is empirically too improbable to consider and wouldn't be that much better anyway.)

Though I used to use C++ for just about everything a few years ago, I'm beginning to strongly feel that C is preferrable in low-level tasks that need to be handled by either C or C++ and everything else should be done in some other language entirely. (Only possible exceptions being some specific high-performance problem domains, wrt. Blitz++)

+8  A: 

Why limit speaking in English? Perhaps you'd be a more creative author in Serbian.

That's the same argument, with obvious fallacies. If you have a task, and your comfortable tools solve the task efficiently, you'll likely use your comfortable tools for good reason.

If I spoke both fluent English and fluent Serbian, I'm sure I would be more creative. Do you disagree?
@Neil indeed, but the effort required to learn Serbian might not be justified to solve my current creativity block.
I think Arno is highlighting the fact that you're not writing for the CPU, you're writing for your coworkers to read, and your other libraries to link, and so on. After all, if I was just going for expressivity and speed, I'd write in OCaml.
+3  A: 

I use C++ with C programming for two reasons:

  • vector and string to get the array memory management away from me
  • strict type checking and casts to warn and/or catch allthe nuisances I would miss otherwise.

So it is C really borrowing a few c++ but using the c++ compiler as much as I can. As someone else says in the answers, I find now I am actually picking up more C++ this way and where C would be too involving, I use C++. Monitor/Lock using RAII is one of these I've used recently when dealing with multi-threaded programs and another similar construct to open/close files.

+12  A: 

In a low-level embedded environment some of the "software engineers" will have an EE background and have barely mastered C. C++ is more complex and some of these guys are simply afraid to learn a new language. Thus C is used as the lowest common denominator. (Before you suggest getting rid of these guys, they're at least as important as the CS majors who don't understand the hardcore analog stuff.)

Speaking from experience in having inherited and maintained both: a horrible design in C is difficult to understand, unwind, and refactor into something usable.

A horrible design in C++ is infinitely worse as random layers of abstraction send your brain careening around the codebase trying to figure out which code is going to be executed in which circumstance.

If I have to work with engineers who I know will not produce great designs, I'd much rather have the former than the latter.

+64  A: 

This is prompted by a an answer I gave to a current question which asks about a generics library for C - the questioner specifically states that they do not want to use C++.

C is a complete programming language. C is not an arbitrary subset of C++. C is not a subset of C++ at all.

This is valid C:

foo_t* foo = malloc ( sizeof(foo_t) );

To make it compile as C++ you have to write:

foo_t* foo = static_cast<foo_t*>( malloc ( sizeof(foo_t) ) );

which isn't valid C any more. (you could use the C-style cast, it which case it would compile in C, but be shunned by most C++ coding standards).

They are not the same language, and if you have an existing project in C you don't want to rewrite it in a different language just to use a library. You would prefer to use libraries which you can interface to in the language you are working in.

Taking the first C file in a project I'm working on, this is what happens if you just swap gcc std=c99 for g++:

sandiego:$ g++ -g  -O1 -pedantic -mfpmath=sse -DUSE_SSE2 -DUSE_XMM3  -I src/core -L /usr/lib -DARCH=elf64 -D_BSD_SOURCE -DPOSIX -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -Wall -Wextra -Wwrite-strings -Wredundant-decls -Werror -Isrc  src/core/kin_object.c -c -o obj/kin_object.o | wc -l
In file included from src/core/kin_object.c:22:
src/core/kin_object.h:791:28: error: anonymous variadic macros were introduced in C99
In file included from src/core/kin_object.c:26:
src/core/kin_log.h:42:42: error: anonymous variadic macros were introduced in C99
src/core/kin_log.h:94:29: error: anonymous variadic macros were introduced in C99
cc1plus: warnings being treated as errors
src/core/kin_object.c:101: error: ISO C++ does not support the ‘z’ printf length modifier
src/core/kin_object.c:160: error: invalid conversion from ‘void*’ to ‘kin_object_t*’
src/core/kin_object.c:227: error: unused parameter ‘restrict’
src/core/kin_object.c:271: error: ISO C++ does not support the ‘z’ printf length modifier
src/core/kin_object.c:271: error: ISO C++ does not support the ‘z’ printf length modifier

In total 69 lines of errors, four of which are invalid conversions, but mostly for features that exist in C99 but not in C++.

It's not like I'm using those features for the fun of it. It would take significant work to port it to a different language.

So it is plain wrong to suggest that

[a] C compiler is almost certainly really a C++ compiler, so there are no software cost implications

There are often significant cost implications in porting existing C code to the procedural subset of C++.

So suggesting 'use the C++ std::queue class' as an answer to question looking for an library implementation of a queue in C is dafter than suggesting 'use objective C' and 'call the Java java.util.Queue class using JNI' or 'call the CPython library' - AFAIK Objective C actually is a proper superset of C (though not C99), and Java and CPython libraries both are callable directly from C without having to port unrelated code to the C++ language.

Of course you could supply a C façade to the C++ library, but once you're doing that C++ is no different to Java or Python.

Pete Kirkham
I agree with most of what you say but a C-style cast with malloc e.g. int * p = (int *)malloc( 32 ) compiles without a warning under gcc with -pedandtic and -std=c99
Yes. C-style cast is quite usual when you use malloc. When using malloc you do it do stay within the c subset. If you want to program C++ style, you would use operator new, not static_cast + malloc.
Saying that C is not a subset of C++ is incredibly pedantic. Sure, you could say that any struct with a member called "class" will not compile, but it's really only minor modifications that are required, and most compilers have options to add the few C-only features to C++.
Kaz Dragon
as far as your malloc example goes, adding a cast wouldn't just be shunned by C++ programmers, but also (especially) by C programmers. There are good reasons to leave out the cast in C code. It's not necessary, and adding it may conceal errors.So yeah, treat them as two distinct languages. +1 :)
Saying C is not a subset of C++ is like saying Python 2.6 is not a subset of Python 3.0; while it's technically true, calling them two separate languages is stretching it a bit far.
BlueRaja - Danny Pflughoeft
@BlueRaja Imagine if Guido had decided not to add objects to his scripting language, and two groups had created mutually incompatible forks of Python to add objects, one with an object model based on Smalltalk, the other with a class system based on Simula. Then Guido continued to improve Python focussing its core use. That's closer to the C/Objective C/C++ situation.
Pete Kirkham
@BlueRaja: They're two distinct languages that share a fairly large common core. If you program in that common core, you're going to wind up doing things that aren't good code in either language. Pick one language to write any given program in, and make it good in that language.
David Thornley
+1  A: 

I think C is more portable. I did some work about 5 years ago porting code to many flavours of unix (AIX,Irix,HPUX,Linux). The C code was easy to port but we had various problems porting some of the C++ code across. Maybe it was just immature development environments but i would much rather use C over C++ for this reason...

Gordon Carpenter-Thompson
Fifteen years ago I was the lead developer for a C++ project targetting HPUX, AIX and Solaris. We had very few C++ portability problems - almost all the ones we did have were with the C system call incompatibilities.
Less than ten years ago, I was on a project using HPUX, Solaris, and Tru64, using the traditional compilers. Our nightlies never built. When we added AIX, we decided to switch to standard C++.
David Thornley
Maybe the people who wrote your code were better coders than the crap i had to deal with :-)
Gordon Carpenter-Thompson
+5  A: 

Native code on a mac is objective-c. Native code on a PC is c (window.h) or c++ (mfc). Both of these environments will let you use c with little or no changes. When I want a library of code to be cross platform ansi c seems like a good choice.

+3  A: 

I can think of several reasons.

There may not be a satisfactory C++ compiler. C++ is a much bigger language, and I've run C compilers on systems that would not be able to handle modern C++.

The questioner, or people he or she works with, may be familiar with C but not C++.

The project may be in C. While it's possible to add some C++ features to C, that can easily lead to an unmaintainable mess. I'd suggest picking one language or the other (usually C++, when practical).

The questioner may have an obsolete view of C++'s learning curve. (When approached correctly, it's easier than C's. Most introductory books I've seen don't approach it correctly.)

Remember that C and C++ are two different languages, and are getting more different over time. Coding in both at once is a bad idea, and using a C-like subset of C++ misses most of the advantages of C++.

David Thornley
+5  A: 

I use C, or at least export a C interface when I write library code.

I don't want ill-defined ABI hassles.

Rhythmic Fistman
+1  A: 

There are three reasons I can think of. One is that C is more suited for embedded systems, due to the small size of its binaries and the wider availability of C compilers on any system. The second is portability: C is a smaller language, and and ANSI C code will compile anywhere. It's easier to break portability in C++. The last one is the language itself. C++ is harder, and is most definitely a very poorly designed language. Torvalds gripes are reported above. You may also want to look at the C++ Frequently Questioned Answers (http://yosefk.com/c++fqa/).

And, if you're intelligent, after looking at the FQA you'll realize it's a hack job by somebody who doesn't really understand C++ but hates it anyway.
David Thornley
+3  A: 

One point I've not seen raised yet, which I think is the most important:

Most of the libraries I use on a daily basis are C libraries with bindings for Python, Ruby, Perl, Java, etc. From what I've seen, it's a lot easier to wrap C libraries with 19 different language bindings than it is to wrap C++ libraries.

For example, I learned Cairo once, and have since used it in 3 or 4 different languages. Big win! I'd rather write a program that can be used again in the future, and writing one that can easily be adopted to other programming languages is an extreme case of this.

I know it's possible to bind C++ libraries, but AFAICT it's not the same. I've used Qt (v3 and v4) in other languages and it's not anywhere near as nice to use: they feel like writing C++ in some other language, not like native libraries. (You have to pass C++ method sigs as strings!)

C++ is probably a better language if you're writing a function to be used once, or if you think all the world is C++. C seems like an easier language if you're designing for language-portability from the start.

+1  A: 

Portability may be an issue. Different to Gordon Carpenter-Thomp's answer, I would suggest that it's rather the runtime support of different versions of libstdc++ on different linux/unix versions. See this link for a good discussion about this. A little excerpt:

The runtime support code used by different parts of a C++ application needs to be compatible. If one part of the program needs to dynamic_cast or catch objects provided by another, both parts must agree on certain implementation details: how to find vtables, how to unwind the stack, and so on.

For C++ and a few other GCC-supported languages with similar features, such details are specified by a C++ ABI. Whenever the ABI used by GCC changes you'll end up with incompatible libraries produced by the different GCC versions. The same is true for plain C, but the C ABI is much simpler and has been around a lot longer so it's fairly stable.

+4  A: 

C has the main advantage that you can just see what is really going on when you look at some piece of code (yeah preprocessor: compile with -E and then you see it). Something that is far too often not true when you look at some C++ code. There you have constructors and destructors that get called implicitly based on scope or due to assignments, you have operator overloading that can have surprising behavior even when it's not badly misused. I admit I'm a control freak, but I have come to the conclusion that this is not such a bad habit for a software developer who wants to write reliable software. I just want to have a fair chance to say that my software does exactly what it is supposed to do and not have a bad feeling in my stomach at the same time because I know there could still be so many bugs in it that I wouldn't even notice when I looked at the code that causes them.

C++ also has templates. I hate and love them, but if anyone says he or she fully understands them I call him/her a liar! That includes the compiler writers as well as the folks involved in defining the standard (which becomes obvious when you try to read it). There are so many absurdly misleading corner cases involved that it's simply not possible to consider them all while you write actual code. I love C++ templates for their sheer power. It's really amazing what you can do with them, but they can likewise lead to the strangest and hardest to find errors one can (not) imagine. And these errors actually happen and not even rarely. Reading about the rules involved to resolve templates in the C++ ARM almost makes my head explode. And it gives me the bad feeling of wasted time having to read compiler error messages that are several 1000 characters long for which I need already 10 minutes or more to understand what the compiler actually wants from me. In typical C++ (library) code you also often find a lot of code in header files to make certain templates possible which in turn makes compile/execute cycles painfully slow even on fast machines and requires recompilation of large parts of the code when you change something there.

C++ also has the const trap. You either avoid const for all but the most trivial use cases or you will sooner or later have to cast it away or to refacor large parts of the code base when it evolves, especially when you are about to develop a nice and flexible OO design.

C++ has stronger typing than C which is great but sometimes I feel like I would be feeding a Tamagotchi when I try to compile C++ code. A large part of the warnings and errors I usually get from it are not really me doing something that wouldn't work, but just things the compiler doesn't like me to do this way or not without casting or putting some extra keywords here and there.

These are just some of the reasons why I don't like C++ for software that I write alone only using some allegedly robust external libraries. The real horror begins when you write code in teams with other people. It almost doesn't matter whether they are very clever C++ hackers or naive beginners. Everybody makes errors, but C++ makes it deliberately hard to find them and even harder to spot them before they happen.

With C++ you are simply lost without using a debugger all the time but I like to be able to verify the correctness of my code in my head and not having to rely on a debugger to find my code running on paths I would never have anticipated. I actually try to run all my code in my head and try to take all the branches it has, even in subroutines etc. and to use a debugger only occasionally just to see how nicely it runs through all the cosy places I prepared for it. Writing and executing so many test cases that all code paths have been used in all combinations with all sorts of strange input data is simply impossible. So you might not know of the bugs in C++ programs but that doesn't mean they are not there. The larger a C++ projects gets the lower becomes my confidence that it will not have lots of undetected bugs even if it runs perfectly with all the test data we have at hand. Eventually I trash it and start anew with some other language or combination of other languages.

I could go on but I guess I made my point clear by now. All of this has made me feel unproductive when I program in C++ and made me loosing confidence in the correctness of my own code which means I won't use it anymore while I still use and rely on C code that I wrote more than 20 years ago. Maybe it's simply because I'm not a good C++ programmer or maybe beeing quite good in C and other languages allows me to recognize what a lamer I actually am when it comes to C++ and that I will never be able to fully comprehend it.

Life is short...

+1, couldn't agree more.
This sounds remarkably parallel to Linus's argument. (Less of an object context = easier to understand.)
Warren P