C++ growing pains
Still mucking about with C++ at work. Here’s some of the stuff that bothers me lately.
Header file hell. Much like DLL hell on windows, or RPM hell (before yum), header file hell is, I suspect, quite common in C++, and is one of the main reasons it’s not my favorite language.
Typically, with C++, as you try to solve whatever problem you’re trying to solve (means: get the computer to do some useful work) you are kind of forced to do a bunch of “extra” work, figuring out how to frame the problem in terms of objects and classes, not really that big a deal. But, C++ being, (or trying to be) a strongly typed language, encourages the use of custom enumerated types (over #defines, say), That means, if you want classes to communicate with each other without converting from, say, ints to these enums, both classes have to include the header file that defines these enumerated types. Which means there’s a good chance the typedef for the enumeration cannot reside in the header definition file for either class, at least not without putting some thought into it, and moving things around a bit. Why? Because, lets say both (of a mere two) classes define some custom enumeration types, and each class needs to communicate with the other in some way using those types. In that case, if each class includes the header file of the other, and the header file contains guard #ifdefs to prevent being included twice. Well, if there is a circular dependency, things get a bit sticky and non-obvious. You’ve got to sort it out in one of a number of ways. The easiest way is probably to take these types and separate them out into their own headers. Fine. But look at the time it takes to sort all this out. In C, the params would have been ints, everybody automatically knows what an int is, and #defines would do the job pretty effortlessly, albeit with less compiler meddling to make sure you’re doin’ it right.
So, anyway, when I left work today, I was in that particular corner of header file hell, from which I will have to extricate myself tomorrow.
There are other corners of header file hell. Suppose you want to try to reuse some C++ code. If you are very lucky, the code will have been designed to be reused, and designed to have been reused in just the manner you’re wanting to reuse it. More likely, the code isn’t quite so well designed. Instead, it is within a class which is designed such that it fits in well with whatever application it’s embedded in. This embedding entails references to all sorts of other classes in the application, types, etc. As you try to extricate the code you’re interested in for reuse, you find yourself dragging along more and more header files and classes in an ever expanding network, until, in an epiphany, you realize that this approach will lead you to suck in the entire application eventually. At that point, you start cutting and pasting bits, and reworking the code to fit into your problem space.
Well, that’s the bigger of the nuisances I’ve been facing. There are some smalelr ones as well.
whoDecidedThatIdentifiersLikeThisAreEasyToRead? WasItSomeGermanGuy? iHearGermansTendToBuildCompoundWordsInThisWay. ByWhichIMeanCapitializingWordsButOtherwiseJustCrammingThemTogether. VeryReadableDon’tYouThink?
Why do C++ people like identifiers like that? Are they retarded? Brainwashed? I mean, English sentences, in general, consist mostly of uncapitalized words separated by spaces. That is the most readable way of writing text, and that’s what you will find in every instance of fiction, newspaper journalism, magazines, etc., (except possibly some very esoteric and pathological exceptions which are deviating only to make some weird point. ) The closest approximation to this for C or C++ identifiers is lowercase words separated by underscores (as spaces are not an option.)
So, why, oh why, are C++ programmers so fond of this crazy way of naming variables and functions? I have no idea.
Another nit. I have become used to the linux kernel way of formatting code in the last 6 or 8 years or so. This way of formatting code involves indenting code with tabs, not spaces. And tabs indicate and indent of 8 spaces, not 4, not 3, not 2. When I started on this project, I asked around, “hey, are there any coding conventions, style guidlines, etc., that I should be following? By default, I’m apt to write code formatted like what you’d see in the linux kernel, is that ok?” “Sure, we’re not religious about that,” I was told. Hmm. Well, today, I get a call. “Hey, I noticed you’re using tabs.” “yeah…. is that ok?” “well, we’d prefer not.” Oooookay. Could’ve told me that earlier. The problem with this is, my editor of choice is vi. Vi, by default, is very tab friendly, provided you agree that a tab means an 8 space indent. It has various commands that know that (e.g. “<<” will move a line over by one tabstop, “10>>” will move ten lines right by one tab stop, etc. These things are habits that are hardwired into my fingers by now.
Anyway, I converted all my C++ files to use 3 spaces in place of every tab. And, I found (via codeblog that I can add some stuff to the end of the file like this:
// Local Variables: // c-basic-offset: 3 // indent-tabs-mode: nil // End: // // vim: et sts=3 sw=3
The above teaches vim that, around these parts, there is no such thing as a tab, when you think “tab”, put 3 spaces. It even makes “<<” and “>>” work as well. So I’m glad to have found that. I don’t have to retrain my fingers. (I couldn’t retrain my fingers anyway, as there’s plenty of code I still have to work on that adheres to the “no spaces, only tabs” doctrine, so I’m doubly happy that I found a solution that automatically (once implemented) limits its application to only those files which need it, and leaves default behavior alone.)
I had another idea today, while thinking about the C++ identifiers and using capital letters vs. lowercase, and underscores (or not.) It occurred to me that both the underscores and the capital letters require one to use the shift key, which is, although easily learned, an inefficient and overly strenuous finger move, given how frequently it must be executed. I started thinking about those keyboards with the split space bar they had for awhile, the ones where half the space bar was made into a backspace key. Evidently that didn’t go over too well, as I don’t recall having seen those around lately, but they were around for about a year… maybe that was 2 years ago? I can’t remember. Anyway, it occurs to me that if you could get one of those keyboards, and, for whichever thumb you don’t normally use for space (I tend to use my right thumb exclusively for space, so for me, the left half of the space bar is unused), dedicate that to the underscore. This way, C style identifiers could be typed in very nearly the normal fashion, just use the “wrong” thumb to hit the space bar… Brilliant idea, no?