Defective C++
Part one of many
September 27, 2018People can and do write bad code in every language that has ever existed. However, C++ seems to be specially designed to facilitate writing unreadable and unmaintainable code. Here are some tips to enhance your job security.
- Obscure your types
Use subclasses, aliases, and typedefs to hide what arguments a function really takes. Think of them like little shell companies. They don't have to do anything other than make it harder to figure out what's what. This is an enabling technique for others that follow. - Require references, don't provide defaults
In C, it's common for a function that takes a pointer to use NULL for some default kind of behavior. You can't allow this in C++; it's too convenient. Use references instead of pointers so that NULL is not an option, then don't provide a default value of the thoroughly obscured type (see above) that you require. That way, callers will have to slog through all the obfuscation to find what fields they need to set themselves. - Use templates as much as possible
Use complex types (function/method pointers with many arguments are good) and other template types within your template definitions. Add default arguments that literally nobody ever uses, or could even figure out how to use. Your goal is to use template instantiation to make the compiler generate signatures so long that a single frame in a stack trace scrolls off the screen. - Use the same method name everywhere
This has two advantages. First, it makes it impossible for anything less than a full class-aware IDE to find references to the right version of the method. Second, you can make it impossible to know except at run time which version will actually get called. Double the fun! - Break that rule occasionally
Just when somebody has gotten used to using plain old string searches to pick through the many instances of a method name to get the one at the level they want, hit them with a different name at the most important level. - Abuse exceptions
Never return an error when you can throw an exception. It's not only more inscrutable. It's less efficient too, especially if you've done the work to create complex exception types with heavy-weight constructors ... but never put anything useful like the place it was thrown into that data. In callers, catch the exceptions you know about, then add a silent catcher for anything else. That way, whenever something you call throws a different exception than it used to, it will be eaten silently instead of flagged as something worth looking into. - Log the mundane, ignore the unusual
OK, this one's not specific to C++. It works in any language. Spew log messages for the most common and uninteresting events. Why create a gigabyte log file when you can go for a terabyte? Make the user wish they hadn't left logs on the root disk. If anything noteworthy happens, for heaven's sake keep quiet about it. If you don't want to explain or deal with it, why would you want to let anybody else know about it? Pretend everything's fine.
I'm sure I'll find more of these some day. Do you have a favorite?