204 C++ Comparing C++ to COBOL is unfair to COBOL, which actually was a marvelous feat of engineering, given the technology of its day. The only marvelous thing about C++ is that anyone manages to get any work done in it at all. Fortunately, most good programmers know that they can avoid C++ by writing largely in C, steering clear of most of the ridiculous fea- tures that they’ll probably never understand anyway. Usually, this means writing their own non-object-oriented tools to get just the features they need. Of course, this means their code will be idiosyncratic, incompatible, and impossible to understand or reuse. But a thin veneer of C++ here and there is just enough to fool managers into approving their projects. Companies that are now desperate to rid themselves of the tangled, unread- able, patchwork messes of COBOL legacy code are in for a nasty shock. The ones who have already switched to C++ are only just starting to realize that the payoffs just aren’t there. Of course, it’s already too late. The seeds of software disasters for decades to come have already been planted and well fertilized. The Assembly Language of Object-Oriented Programming There’s nothing high-level about C++. To see why, let us look at the prop- erties of a true high-level language: Elegance: there is a simple, easily understood relationship between the notation used by a high-level language and the concepts expressed. Abstraction: each expression in a high-level language describes one and only one concept. Concepts may be described independently and combined freely. Power: with a high-level language, any precise and complete description of the desired behavior of a program may be expressed straightforwardly in that language. A high-level language lets programmers express solutions in a manner appropriate to the problem. High-level programs are relatively easy to maintain because their intent is clear. From one piece of high-level source code, modern compilers can generate very efficient code for a wide variety of platforms, so high-level code is naturally very portable and reusable.
The Assembly Language of Object-Oriented Programming 205 A low-level language demands attention to myriad details, most of which have more to do with the machine’s internal operation than with the prob- lem being solved. Not only does this make the code inscrutible, but it builds in obsolescence. As new systems come along, practically every other year these days, low-level code becomes out of date and must be manually patched or converted at enormous expense. Pardon Me, Your Memory Is Leaking… High-level languages offer built-in solutions to commonly encountered problems. For example, it’s well known that the vast majority of program errors have to do with memory mismanagement. Before you can use an object, you have to allocate some space for it, initialize it properly, keep track of it somehow, and dispose of it properly. Of course, each of these tasks is extraordinarily tedious and error-prone, with disastrous conse- quences for the slightest error. Detecting and correcting these mistakes are notoriously difficult, because they are often sensitive to subtle differences in configuration and usage patterns for different users. Use a pointer to a structure (but forget to allocate memory for it), and your program will crash. Use an improperly initialized structure, and it corrupts your program, and it will crash, but perhaps not right away. Fail to keep track of an object, and you might deallocate its space while it’s still in use. Crash city. Better allocate some more structures to keep track of the struc- tures that you need to allocate space for. But if you’re conservative, and never reclaim an object unless you’re absolutely sure it’s no longer in use, watch out. Pretty soon you’ll fill up with unreclaimed objects, run out of memory, and crash. This is the dreaded “memory leak.” What happens when your memory space becomes fragmented? The rem- edy would normally be to tidy things up by moving the objects around, but you can’t in C++—if you forget to update every reference to every object correctly, you corrupt your program and you crash. Most real high-level languages give you a solution for this—it’s called a garbage collector. It tracks all your objects for you, recycles them when they’re done, and never makes a mistake. When you use a language with a built-in garbage collector, several wonderful things happen: The vast majority of your bugs immediately disappear. Now, isn’t that nice? Your code becomes much smaller and easier to write and under- stand, because it isn’t cluttered with memory-management details.
Previous Page Next Page