Is high-church C++ fair?
I’ve written this article because I mull over these ideas in my head structuring them in an article helps me understand my thoughts but raises more questions, the more I think and write the more questions arise. So, the second reason for writing this article is an appeal for help: I’d really like to know what other people think about these issues, particularly those who are new to C++.
Time to go (again)
Once again it has come time for me to hand over a project and move on. This is a fairly big project, very important to the company, and, as I’m leaving the company it’s important that the hand-over goes smoothly.
The code should be readable to most Overload readers (sorry, no examples), and most would not look out of place in C++ Report, in other words, it’s what I call “high-church C++”, it uses the language to the full, is littered with design pattern references (indeed, the main loop is a command pattern), a few templates, plenty of standard library, and inheritance is used mainly for interface not implementation inheritance.
I can point to reams of books to prove my C++ is good C++: Meyer advocates interface inheritance, Stroustrup templates and the standard library, the FAQ many of the smaller techniques I’ve used and Design Patterns documents many of the techniques my system used. But, does this make the system easy for someone else to understand? In short: does high-church C++ look any different to an inexperienced developer than badly written C++?
Let me also say, that while Java advocates may claim Java is a better language and much of this could not happen in Java, I think it could, pointers and compilers are not the problem, it is the size of the languages, and while Java is smaller than C++ it is not massively smaller.
Choose your church.
First, let me define four types of C++:
- High-church – “the kind of C++ you see in C++ Report” : as I said above, templates, standard library, interface inheritance more important than implementation inheritance, full use of language features and new keywords.
Low-church – “the kind of C++, C programmers write up to the kind of C++ in the MFC” : few templates, roll your own data structures, lots of void casts, implementation inheritance more important than interface inheritance.
- C – “the kind of C++ which is just C with classes” : we can probably all recognise this, and probably wrote a bit of it ourselves in the early days. However, after a short while we are either high-church C++, low-church C++ or, last but not least…..
- Bad C++ – “where the developer writes C and has picked up a few bits of C++ and doesn’t realise what they are doing” : no understanding of copy constructors, inheritance (of all kinds!) used without a clear reason, destructors releasing resources before they are finished with, no standard library, lots of void casts, unnecessary and inappropriate file dependencies.
I have deliberately used the terms high-church and low-church, not only because of well know religious programming wars but because both sides have their arguments (high-church claims to be more object oriented, while low-church claims to be more understandable to average programmers) and because it is easy for high-church to look down on low-church as less than true, while low-church regards high-church as fanatical.
In writing high-church C++ my objectives are:
- to avoid writing code, so I use the standard libraries and reuse what I can in my on code, I also use language constructs and design patterns
- improve maintenance, to quote John Vlassides “the hallmark of good code is that it is changed by adding to it, not hacking it”
- reduce the number of bugs – again, reusing code helps here, but resource control through constructors and destructors helps
- Reduce dependencies i.e. ripple effect of making a code change.
But in doing this, we are not raising the bar for others? E.g. Using the standard library means that a developer must understand the standard library, but if I write my own linked list they need not look further than my own code.
The problem in hand…
Returning to my own project, if I where to take over a similar one, or someone of my experience where to take over this project I do not think they would have a problem. Indeed, they would probably pick up the code and understand it quiet quickly, the abstractions should mean you can understand the high-level side without understanding the details. Only when the details change do you need to understand them.
So may be my question is should really be turned onto management, the developers they hire, appoint to projects and training courses they use. But, most manages (well those I have encountered) gave up programming when they got the keys to the company car. If I actually asked them what I should write, I think I would be told to write low-church C++, but this would take me longer (more code would need to be written and more testing) and I do think it would be less maintainable in the long run. But without two individuals writing the same project in low and high C++ how can we quantify this?
And why stop at low-church C++, why not C? After all a smaller language should be easier to understand?
Maybe my questions should be addressed to the writers of “C++ in 21 days”, or Widget training “4 day C++ course.” Can people really understand it all in 4 days? While an 800 page book may look like overload in reality it hardly scratches the surface.
Maybe the problem is with those who regard developers as “plug compatible” and pay little head to the experience of one developer over another.
Side-step the problem?
My division of low-church and high-church C++ may appear to leave open the option to choose low-church. While this is a short-term option I would argue that it is not possible in the long term. A good developer will grow and will want to use the more advanced features of our language. Even a mediocre developer will, if he or she codes C++ for long enough start to find them, functions which they may not have written (e.g. copy constructor) will eventually bite them and cost them, low-church C++ does not lead to quality software.
What can we do about it?
Given the problem I describe, how do we turn a novice-C++, C with classes, developer into a high-church developer? Or, at least help them maintain a high-church program? As we cannot plug in a C++ memory card to the developers brain we are left with education. Training courses are good but only go so far, who can take in everything they are told on a four day course? Let alone a battery of four day courses.
I suggest a small, core library, of books which each development team should own and everyone should read – including management! I pose the question: “What is the minimum set of books that can be read to fully understand C++?”
I’ll stab at these books, please take issue with my choices:
- Scott Meyers: Effective C++, 0-201-92488-9
- John Lakos: Large Scale C++ Development, 0-201-63362-0
- John Vlassides et al: Design Patterns, 0-201-63361-2
- Bjarne Stroustrup: C++ Programming language, 0-201-88954-4
I suggest the first three should be read from cover to cover, although you may skim and skip where you wish, it’s important to get a feel for the books. Stroustrup is for reference, reading cover to cover may damage your health.
This set of books is not intended to teach C++ but to make a you proficient. What this lists lacks is a good standard library book, I have not read enough to give a definitive answer but my colleague Tim Penhey recommends Nicolai Josuttis’ The C++ Standard Library although I have yet to spend any time with this book.
The other problem with this list is, it assumes some degree of engineering acumen. I think one needs a prior understanding of cohesion, coupling, and the like. What worries me here is that while those who have studied disciplines like computing, engineering or mathematics will a have suitable background, I vividly remember one of Logica’s founders claiming his best programmers had studied “music” and “English literature”. While as regular readers should know, I look to other disciplines for inspiration and ideas I’m not sure a degree in music adds anything to a mainstream career as a developer. (Please, someone, take issue and enlighten me.)
I am sorry to admit, but part of me thinks you have to want to learn this stuff; if you are not born with the geek gene you may never become a true worshiper at the alter of high-church C++; if this is the case, those of us who do worship should ask ourselves if we are being fair to low-church?
(c) Allan Kelly, March 2000