![]() | |
![]() ![]() ![]() |
![]() | Imperfect C++ Practical Solutions for Real-Life Programming By Matthew Wilson |
Table of Contents | |
Prologue: Philosophy of the Imperfect Practitioner |
Hairshirt ProgrammingMany of the textbooks we read, even very good ones, tell you about the ways in which C++ can help you out if you use its features to their full extent, but all too often go on to say "this doesn't really matter" or "that would be taking [rigor] a bit far."More than one former colleague has engaged me in lively debate in a similar vein; the usual arguments amount to "I'm an experienced programmer, and I don't make the mistakes that XYZ would prevent me from doing, so why bother?" Phooey! This is flawed in so many ways. I'm an experienced programmer, and I do at least one stupid thing every day; if I didn't have disciplined habits, it would be ten. The attitude assumes that the code's never going to be seen by an inexperienced programmer. Further, it implies that the code's author(s) will never learn, nor change opinions, idioms, and methodologies. Finally, what's an "experienced programmer" anyway?[2]
These people don't like references, constant members, access control, explicit, concrete classes, encapsulation, invariants, and they don't code with portability or maintenance in mind. But they just love overloading, overriding, implicit conversions, C-style casts, using int for everything, globals, mixing typedefs, dynamic_cast, RTTI, proprietary compiler extensions, friends, being inconsistent in coding styles, making things seem harder than they are. Bear with me while I digress into some historical allegory. After being made Archbishop of Canterbury in 1162 by Henry II, Thomas À Beckett underwent a transformation in character, reforming from his materialistic ways and developing both a genuine concern for the poor and a profound sense of remorse for his former excesses. As his body was being prepared for burial, Beckett was found to be wearing a coarse, flea-infested hairshirt. It was subsequently learned that he had been scourged daily by his monks. Ouch! Now, personally I think that's taking repentance and soul purging a tad far. Nevertheless, having in my earlier days made cavalier use of the power of C++ to create all manner of fell perversions (see Appendix B), these days I try to take a more temperate approach, and thus wear a bit of a hairshirt when programming.[3]
Of course, I don't mean I kneel on a gravel floor, or that I've punched nails through the back of my Herman-Miller, or have stopped blasting cooking dance music while I code. No, I mean I make my software treat me as harshly as I can whenever I try to abuse it. I like const—a lot of it—and use it whenever I can. I make things private. I prefer references. I enforce invariants. I return resources from where I got them, even if I know the shortcut is safe; "Well, it worked fine on the previous version of the operating system. It's not my fault you upgraded!" I've enhanced C++'s type checking for conceptual typedefs. I use nine compilers, through a tool (see Appendix C) that makes it straightforward to do so. I use a more potent NULL. This is not done for a nomination for the "programmer of the year" award. It's simply a consequence of my being lazy, as all good engineers are wont to be. Being lazy means you don't want to find bugs at run time. Being lazy means you don't want to ever make the same mistake twice. Being lazy means making your compiler(s) work as hard as possible, so that you don't have to. |
![]() | |
![]() ![]() ![]() |