Friday, May 01, 2009

C++ is a horrible language

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.


Dave Cunningham said...

Hey, just wanted to say that I've enjoyed reading through your blog and will follow it in the future. I completely agree with your comments about C++. My biggest beef with it is binary compatibility of types and how that severely restricts you from providing a dynamic API with solid parameter types (such as std::basic_string.)

bc said...

There is an interesting irony in C++. PL/I was invented to be the new "super language" and on Multics they attempted to use it to write the OS. But PL/I proved to be inefficient and slow on the machines of the day, which led K&R to develop the lean and mean C for developing Unix.

Turning full circle, C++ has become the new super-language, but itself leads to bloated inefficient code. We can get away with that, because machines are so much faster.

I've mostly avoided C++ by working in embedded real-time, but even there C++ finds a foothold as CPU clock rates go up.

Adam Smith said...

Thanks for the comments Dave and bc, makes it feel more worthwhile to write entries when I know somebody actually care to read the stuff I write ;-)

Interesting that thing about PL/I. I guess the problem with C++, is that theoretically it is a very efficient language. You can write faster code in it than C. But in practice it encourages practices and ways of thinking that push you into writing bloated and slow code.

theoriginalanomaly said...

I have came to the same conclusion about C++ as well. I am really pretty excited about Vala, as it is basically a new ++C that doesn't suck. And it compiles to C. It does have about as much overhead as C++, but with the simplicity for the programmer as a java or C#.

Adam Smith said...

theoriginalanomaly, I looked a bit at Vala. If I was doing Linux and Gtk development I'd definitly give it a try.

Still my impression is that Vala is fairly traditional. I think there are more exicting ideas in Go, Rust, Swift, Kotlin, Julia, Clojure etc. If I was doing typical C++ development like I used to where performance is important I'd invest in learning Rust. Now I am an iOS developer so Swift is the name of the game. But I like playing with Julia. Great language for data analysis, algorithms etc.

Go is quite nice for lowlevel stuff. E.g. look at cryptography code written in Go. Because it supports pointers and size is part of the type of an array it is very handy when fiddling with arrays of bytes or integers as often is the case with cryptography.

If you are interested in programming languages like me, then check out my newer blogs at:

Where I've written more about Go, Swift and Julia.