Over the years my dislike of C++ has increased. It seems like the more I know about language the more I dislike it. I believe that Linus Torvalds summed it up pretty well when he said:
IOW, C++ is in that inconvenient spot where it doesn’t help make things
simple enough to be truly usable for prototyping or simple GUI
programming, and yet isn’t the lean system programming language that C is
that actively encourags you to use simple and direct constructs
This comment is from the now infamous git mailing list, where Linus Torvalds details why you think C++ is a horrible language. I think the problem for most people dispute this point is that they don’t get what latest means when he says that C++ is a horrible language. For creating higher-level abstractions and large programs C++ is obviously better. But that is a silly way to compare the two languages. For what C. has been designed for does his job very well. It allows you to write low-level and high-performance code. C++ on the other hand is a jack of all trades and master of none.
The classic rebuttal of this from C++ fans, is that C++ can do everything that C. can do, so there’s no need to use C. But this is simply not true. A C programmer can read a statement and know fairly well how many objects are allocated on the heap or on the stack and know how many function calls are performed. This is almost impossible in C++. Due to the existence of constructors, descriptors and operator overloading a wise things can happen in the simplest statements.
In theory you can write C++ code which has higher performance than corresponding C code. However since C++ gives you less control over what happens in each statement, there is a higher chance that you doing something which kills performance then in C.
The other classic statement from C++ fans is that:
you can just use the subset of the language which you are comfortable with.
However even a small subset of C++ requires that you understand quirky attributes of the language. For instance, I would argue that using statically initialized variables is nothing fancy. You can do this easily in C. However in C++ this require a lot more care. Unlike C declaring static variables in C++ can cause code to run during initialization. Typically this will be the code for the constructors of the objects statically initialized. You cannot control in which sequence this code is executed. This can cause very hard to find bugs.
This is just one of many examples. You can just read Scott Meyers book Effective C++ to find a long list of stuff you have to be aware of C++ to not shoot yourself in the foot. There are loads of books like this for C++. I do not know of any comparable books for the C-language.
The C-language is in no way perfect, but I simply don’t get why the deficiencies of C, should be remedied by using C++. If you need higher level abstractions or a more type safe language why not use other languages like OCaml, Haskell, LISP or Python? Say you select Python. It is not as high performance as C++, but in the places where you need performance she could implement the functionality in C-language. There is no need to use C++, because you’re not writing a large program where you need to be able to build abstractions. You are building a simple module, where advanced abstractions are not needed.
People will point to libraries like Qt as proof that you can write easy to understand code in C++. I however think it’s proof of the opposite. Not because I think Qt is bad. Quite the contrary is one of the better GUI toolkits out there. However that is not because C++ is a great language but because they essentially invented their own language by adding a preprocessor. It’s not that different from how Objective-C was originally made by adding a preprocessor to the C-language. In C++ was such a versatile and flexible language as some claim, there would never have been a need for the moc preprocessor.
I am not saying this as C developer who has just started dabbling in C++. I’ve been doing C++ all my professional life. I never used C very much at all. The realizations have just dawned upon me while working several years on large software projects in C++. Very little of our time is spent on writing performance critical code. In fact most of it is some sort of glue code. Code to make different components talk to each other and tell each other about changes that have just happened to them. All stuff that a script language like Python would have done much better.