In my current project, I’m writing quite a bit of C++ code. Granted it’s front-end C++ code with Qt, so it’s not what one would call “vanilla C++”, but it has been enough to remind myself of what I like and what I really don’t miss in the language. Let’s try to build a list:
Things I didn’t miss
- Unhelpful compiler error messages: C++ is a very powerful language, but quite low level. And who suffers the most with this power is the compiler. Sometimes it’s quite clueless in being able to correctly point out to you what is wrong. I’ll give an example (although I don’t have the exact error message strings with me right now): I’ve added a lot of different lines of code that used some class, but barely touched that class definition and then suddenly I started getting errors compiling the class complaining that “QObject::QObject cannot access private member declared in class QObject”. QObject is the parent class of my class. The error message pointed to a line of code in QObject that was something like:
So what could I do if the problem was in somebody else’s code? And what did I do to cause this? Well, the answer was that I by accident had a line that was like this:
MyClass obj = MyClass(“construct-me”);
What it means it that it was creating a new member of my class and then creating yet another one using the copy constructor. however, the copy constructor is private in QObject, so it was throwing an error. The tricky thing is that it doesn’t throw an error in the code that was calling it, but within the QObject code. And there went 30 minutes of my life tracking this problem…
- Slow compilation: I think this is more because I’ve been doing a lot of Java lately using eclipse that has a pretty good incremental compiler that allows me to most of the time not worry at all with compilation. I can finish writing something, click save and then click run and it’s running. There is no multiple seconds, sometimes minutes if I touch a file that has too many dependencies, of wait time.
- Garbage collection: I’m not against not having a garbage collector as a concept. But it does make coding slower, especially when you want to build things that are a little bit more dynamic. You have to keep references to things around and remember that somewhere you need to release them. And depending on how the code goes, you might change the decision mid-way and get nice exception of trying to delete the same object twice. The result is that I find myself writing less clean code, or over-copying objects, simply because I know that this way I can always track my references.
- Weaker library support: some C++ libraries are quite powerful, Qt included. However, it’s very common for me to find myself in situations where I have to write my own solution for simple things, like JSON output, simply because the libraries that are out there don’t quite support the data structures that I’m using, so it takes more code to keep changing data structures than writing the whole code myself.
What I like:
- Binary control: sometimes you just want to do some binary operations and know exactly how many bits you are sending and reading (very important when you are doing cryptographic signing and CRC calculations), so it’s nice to know the size of the things you are handling, and being able to easily move between higher-level object representation to the actual bytes that are being stored.
- Binary understandability: this is actually a little bad at the same time. A coulple of weeks ago I was trying to track why something that I wanted to do wasn’t actually working. The piece that wasn’t working was inside a piece of third-party code (WebKit to be more exact) and I wasn’t quite able to tell what was going on. I had access to the source code, but not the same one that my libraries were built againt. My solution: look at the assembly generated and then map back to the code that I had. It wasn’t that hard to do, and provided me with precise information of what was going on (a “feature” in WebKit) and partial information on how to get around it.
- No 10 layers of frameworks: that’s probably something that is more typical with Java than other languages. When you get into a “production-level” codebase that you don’t know in Java, you will usually find yourself in layers and layers of framework code that ties your code together. This framework greatly reduces the amount of code that you need to write to get some things done, but makes undestanding the execution flow quite hard. So working on an existing codebase can be daunting. In C++ there is some of framework too, but usually not as much (partly because of reasons #3 and #4 above). This makes it much easier to get into the code and figure out what is going on and when.
So, would I choose C++ as a preferred programming language? Probably not, but I do have some appreciation for people that actually do. What I’m not looking forward to is writing C for one of my future projects…