diff --git a/README.md b/README.md index f446d7f..9d94959 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ **Roedy Green** [**Canadian Mind Products**](http://mindprod.com/jgloss/unmain.html) +Reproduced [with permission from the author](https://github.com/Droogans/unmaintainable-code/issues/3#issuecomment-235317722), circa 2015 + * * * ## Introduction @@ -61,7 +63,7 @@ To break the boredom, use a thesaurus to look up as much alternate vocabulary as #### Use Plural Forms From Other Languages -A VMS script kept track of the "statii" returned from various "Vaxen". Esperanto , [Klingon](http://www.kli.org/) and [Hobbitese](http://www.chriswetherell.com/hobbit/default.asp target=) qualify as languages for these purposes. For pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world peace. +A VMS script kept track of the "statii" returned from various "Vaxen". Esperanto , [Klingon](http://www.kli.org/) and Hobbitese qualify as languages for these purposes. For pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world peace. #### CapiTaliSaTion @@ -126,12 +128,12 @@ This trick works especially well in Ada, a language immune to many of the standa #### When To Use i -Never use `i` for the innermost loop variable. Use anything but. Use `i` liberally for any other purpose especially for non-int variables. Similarly use `n` as a loop index. +Never use `i` for the innermost loop variable. Use anything but `i`. Use `i` liberally for any other purpose especially for non-int variables. Similarly use `n` as a loop index. #### Conventions Schmentions -Ignore the [Sun Java Coding Conventions](http://java.sun.com/docs/codeconv/), after all, Sun does. Fortunately, the compiler won't tattle when you violate them. The goal is to come up with names that differ subtlely only in case. If you are forced to use the capitalisation conventions, you can still subvert wherever the choice is ambigous, e.g. use *both* _input**F**ile**n**ame_ and _input**f**ile**N**ame_. Invent your own hopelessly complex naming conventions, then berate everyone else for not following them. +Ignore the [Sun Java Coding Conventions](http://web.archive.org/web/20091003224540/http://java.sun.com/docs/codeconv/), after all, Sun does. Fortunately, the compiler won't tattle when you violate them. The goal is to come up with names that differ subtly only in case. If you are forced to use the capitalisation conventions, you can still subvert wherever the choice is ambiguous, e.g. use *both* _input**F**ile**n**ame_ and _input**f**ile**N**ame_. Invent your own hopelessly complex naming conventions, then berate everyone else for not following them. #### Lower Case l Looks a Lot Like the Digit 1 @@ -171,7 +173,7 @@ Hungarian Notation is the tactical nuclear weapon of source code obfuscation tec - Insist on using "c" for const in C++ and other languages that directly enforce the const-ness of a variable. - - Seek out and use Hungarian warts that have meaning in languages other than your current language. For example insist on the PowerBuilder `l_` and `a_` {local and argument} scoping prefixes and always use the VB-esque style of having a Hungarian wart for every control type when coding to C++. Try to stay ignorant of the fact that megs of plainly visible MFC source code does not use Hungarian warts for control types. + - Seek out and use Hungarian warts that have meaning in languages other than your current language. For example, insist on the PowerBuilder `l_` and `a_` {local and argument} scoping prefixes and always use the VB-esque style of having a Hungarian wart for every control type when coding to C++. Try to stay ignorant of the fact that megs of plainly visible MFC source code do not use Hungarian warts for control types. - Always violate the Hungarian principle that the most commonly used variables should carry the least extra information around with them. Achieve this end through the techniques outlined above and by insisting that each class type have a custom wart prefix. Never allow anyone to remind you that **no** wart tells you that something **is** a class. The importance of this rule cannot be overstated if you fail to adhere to its principles the source code may become flooded with shorter variable names that have a higher vowel/consonant ratio. In the worst case scenario this can lead to a full collapse of obfuscation and the spontaneous reappearance of English Notation in code! @@ -181,14 +183,14 @@ Hungarian Notation is the tactical nuclear weapon of source code obfuscation tec - Use to your advantage the principle that the human brain can only hold 7 pieces of information concurrently. For example code written to the above standard has the following properties: - * a single assignment statement carries 14 pieces of type and name information. - * a single function call that passes three parameters and assigns a result carries 29 pieces of type and name information. + * A single assignment statement carries 14 pieces of type and name information. + * A single function call that passes three parameters and assigns a result carries 29 pieces of type and name information. * Seek to improve this excellent, but far too concise, standard. Impress management and coworkers by recommending a 5 letter day of the week prefix to help isolate code written on `Monam` and `FriPM`. * It is easy to overwhelm the short term memory with even a moderately complex nesting structure, **especially** when the maintenance programmer can't see the start and end of each block on screen simultaneously. #### Hungarian Notation Revisited -One followon trick in the Hungarian notation is "change the type of a variable but leave the variable name unchanged". This is almost invariably done in windows apps with the migration from Win16: +One follow-on trick in the Hungarian notation is "change the type of a variable but leave the variable name unchanged". This is almost invariably done in windows apps with the migration from Win16: ```c WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam) @@ -208,7 +210,7 @@ If you have to define a structure to hold data for callbacks, always call the st #### Obscure film references -Use constant names like `LancelotsFavouriteColour` instead of `blue` and assign it hex value of `$0204FB`. The color looks identical to pure blue on the screen, and a maintenance programmer would have to work out `0204FB` (or use some graphic tool) to know what it looks like. Only someone intimately familiar with Monty Python and the Holy Grail would know that Lancelot's favorite color was blue. If a maintenance programmer can't quote entire Monty Python movies from memory, he or she has no business being a programmer. +Use constant names like `LancelotsFavouriteColour` instead of `blue` and assign it a hex value of `$0204FB`. The color looks identical to pure blue on the screen, and a maintenance programmer would have to work out `0204FB` (or use some graphic tool) to know what it looks like. Only someone intimately familiar with Monty Python and the Holy Grail would know that Lancelot's favorite color was blue. If a maintenance programmer can't quote entire Monty Python movies from memory, he or she has no business being a programmer. ## Camouflage @@ -218,19 +220,18 @@ Much of the skill in writing unmaintainable code is the art of camouflage, hidin #### Code That Masquerades As Comments and Vice Versa -Include sections of code that is commented out but at first glance does not appear to be. +Include sections of code that are commented out but at first glance do not appear to be. ```js -for(j=0; j. */ -class clever_SSInc - { +class clever_SSInc { .. . - } +} ``` If possible, put insulting stuff in syntactically significant parts of the code, as well as just the comments so that management will probably break the code if they try to sanitise it before sending it out for maintenance. @@ -463,11 +461,11 @@ On a method called makeSnafucated insert only the JavaDoc `/* make snafucated */ > _The cardinal rule of writing unmaintainable code is to specify each fact in as many places as possible and in as many ways as possible._ - Roedy Green -The key to writing maintainable code is to specify each fact about the application in only one place. To change your mind, you need change it in only one place, and you are guaranteed the entire program will still work. Therefore, the key to writing unmaintainable code is to specify a fact over and over, in as many places as possible, in as many variant ways as possible. Happily, languages like Java go out of their way to make writing this sort of unmaintainable code easy. For example, it is almost impossible to change the type of a widely used variable because all the casts and conversion functions will no longer work, and the types of the associated temporary variables will no longer be appropriate. Further, if the variable is displayed on the screen, all the associated display and data entry code has to be tracked down and manually modified. The Algol family of languages which include C and Java treat storing data in an array, Hashtable, flat file and database with **totally** different syntax. In languages like Abundance, and to some extent Smalltalk, the syntax is identical; just the declaration changes. Take advantage of Java's ineptitude. Put data you know will grow too large for RAM, for now into an array. That way the maintenance programmer will have a horrendous task converting from array to file access later. Similarly place tiny files in databases so the maintenance programmer can have the fun of converting them to array access when it comes time to performance tune. +The key to writing maintainable code is to specify each fact about the application in only one place. To change your mind, you need to change it in only one place, and you are guaranteed the entire program will still work. Therefore, the key to writing unmaintainable code is to specify a fact over and over, in as many places as possible, in as many variant ways as possible. Happily, languages like Java go out of their way to make writing this sort of unmaintainable code easy. For example, it is almost impossible to change the type of a widely used variable because all the casts and conversion functions will no longer work, and the types of the associated temporary variables will no longer be appropriate. Further, if the variable is displayed on the screen, all the associated display and data entry code has to be tracked down and manually modified. The Algol family of languages which include C and Java treat storing data in an array, Hashtable, flat file and database with **totally** different syntax. In languages like Abundance, and to some extent Smalltalk, the syntax is identical; just the declaration changes. Take advantage of Java's ineptitude. Put data you know will grow too large for RAM, for now into an array. That way the maintenance programmer will have a horrendous task converting from array to file access later. Similarly place tiny files in databases so the maintenance programmer can have the fun of converting them to array access when it comes time to performance tune. #### Java Casts -Java's casting scheme is a gift from the Gods. You can use it without guilt since the language requires it. Every time you retrieve an object from a Collection you must cast it back to its original type. Thus the type of the variable may be specified in dozens of places. If the type later changes, all the casts must be changed to match. The compiler may or may not detect if the hapless maintenance programmer fails to catch them all (or changes one too many). In a similar way, all matching casts to `(short)` need to be changed to `(int)` if the type of a variable changes from `short` to `int`. There is a movement afoot in invent a generic cast operator `(cast)` and a generic conversion operator `(convert)` that would require no maintenance when the type of variable changes. Make sure this heresy never makes it into the language specification. Vote no on RFE 114691 and on genericity which would eliminate the need for many casts. +Java's casting scheme is a gift from the Gods. You can use it without guilt since the language requires it. Every time you retrieve an object from a Collection you must cast it back to its original type. Thus the type of the variable may be specified in dozens of places. If the type later changes, all the casts must be changed to match. The compiler may or may not detect if the hapless maintenance programmer fails to catch them all (or changes one too many). In a similar way, all matching casts to `(short)` need to be changed to `(int)` if the type of a variable changes from `short` to `int`. There is a movement afoot to invent a generic cast operator `(cast)` and a generic conversion operator `(convert)` that would require no maintenance when the type of variable changes. Make sure this heresy never makes it into the language specification. Vote no on RFE 114691 and on genericity which would eliminate the need for many casts. #### Exploit Java's Redundancy @@ -517,10 +515,9 @@ Go wild with encapsulation and oo. For example: ```java myPanel.add( getMyButton() ); -private JButton getMyButton() - { +private JButton getMyButton() { return myButton; - } +} ``` That one probably did not even seem funny. Don't worry. It will some day. @@ -535,7 +532,7 @@ Lots of them. Move data between the arrays in convoluted ways, say, filling the #### Mix and Match -Use both accessor methods and public variables. That way, you can change an object's variable without the overhead of calling the accessor, but still claim that the class is a "Java Bean". This has the additional advantage of frustrating the maintenence programmer who adds a logging function to try to figure out who is changing the value. +Use both accessor methods and public variables. That way, you can change an object's variable without the overhead of calling the accessor, but still claim that the class is a "Java Bean". This has the additional advantage of frustrating the maintenance programmer who adds a logging function to try to figure out who is changing the value. #### Wrap, wrap, wrap @@ -565,9 +562,9 @@ Instead of using a parameter to a single method, create as many separate methods Make as many of your variables as possible static. If _you_ don't need more than one instance of the class in this program, no one else ever will either. Again, if other coders in the project complain, tell them about the execution speed improvement you're getting. -#### Cargill's Quandry +#### Cargill's Quandary -Take advantage of Cargill's quandary (I think this was his) "any design problem can be solved by adding an additional level of indirection, except for too many levels of indirection." Decompose OO programs until it becomes nearly impossible to find a method which actually updates program state. Better yet, arrange all such occurrences to be activated as callbacks from by traversing pointer forests which are known to contain every function pointer used within the entire system. Arrange for the forest traversals to be activated as side-effects from releasing reference counted objects previously created via deep copies which aren't really all that deep. +Take advantage of Cargill's quandary (I think this was his) "any design problem can be solved by adding an additional level of indirection, except for too many levels of indirection." Decompose OO programs until it becomes nearly impossible to find a method which actually updates program state. Better yet, arrange all such occurrences to be activated as callbacks by traversing pointer forests which are known to contain every function pointer used within the entire system. Arrange for the forest traversals to be activated as side-effects from releasing reference counted objects previously created via deep copies which aren't really all that deep. #### Packratting @@ -619,11 +616,7 @@ Within the body of a loop, assume that the loop action is successful and immedia #### Local Variables -Within the body of a loop, assume that the loop action is successful and immediately update all pointer variables. If an exception is later detected on that loop action, back out the pointer advancements as side effects of a conditional expression following the loop body. - -#### Reduce, Reuse, Recycle - -If you have to define a structure to hold data for callbacks, always call the structure `PRIVDATA`. Every module can define its own `PRIVDATA`. In VC++, this has the advantage of confusing the debugger so that if you have a `PRIVDATA` variable and try to expand it in the watch window, it doesn't know which `PRIVDATA` you mean, so it just picks one. +Never use local variables. Whenever you feel the temptation to use one, make it into an instance or static variable instead to unselfishly share it with all the other methods of the class. This will save you work later when other methods need similar declarations. C++ programmers can go a step further by making all variables global. #### Configuration Files @@ -659,18 +652,17 @@ Always look for the most obscure way to do common tasks. For example, instead of ```c char *p; -switch (n) -{ -case 1: - p = "one"; - if (0) -case 2: - p = "two"; - if (0) -case 3: - p = "three"; - printf("%s", p); - break; +switch (n) { + case 1: + p = "one"; + if (0) + case 2: + p = "two"; + if (0) + case 3: + p = "three"; + printf("%s", p); + break; } ``` @@ -713,18 +705,17 @@ d = c; Smuggle octal literals into a list of decimal numbers like this: ```java -array = new int [] -{ -111, -120, -013, -121, +array = new int [] { + 111, + 120, + 013, + 121, }; ``` #### Convert Indirectly -Java offers great opportunity for obfuscation whenever you have to convert. As a simple example, if you have to convert a double to a String, go circuitously, via Double with `new Double(d).toString()` rather than the more direct `Double.toString(d)`. You can, of course, be far more circuitous than that! Avoid any conversion techniques recommended by the Conversion Amanuensis. You get bonus points for every extra temporary object you leave littering the heap after your conversion. +Java offers a great opportunity for obfuscation whenever you have to convert. As a simple example, if you have to convert a double to a String, go circuitously, via Double with `new Double(d).toString()` rather than the more direct `Double.toString(d)`. You can, of course, be far more circuitous than that! Avoid any conversion techniques recommended by the Conversion Amanuensis. You get bonus points for every extra temporary object you leave littering the heap after your conversion. #### Nesting @@ -732,7 +723,7 @@ Nest as deeply as you can. Good coders can get up to 10 levels of `( )` on a sin #### Numeric Literals -If you have an array with 100 elements in it, hard code the literal 100 in as many places in the program as possible. Never use a static final named constant for the 100, or refer to it as `myArray.length`. To make changing this constant even more difficult, use the literal 50 instead of 100/2, or 99 instead of 100-1. You can futher disguise the 100 by checking for `a == 101` instead of `a > 100`, or `a > 99` instead of `a >= 100`. +If you have an array with 100 elements in it, hard code the literal 100 in as many places in the program as possible. Never use a static final named constant for the 100, or refer to it as `myArray.length`. To make changing this constant even more difficult, use the literal 50 instead of 100/2, or 99 instead of 100-1. You can further disguise the 100 by checking for `a == 101` instead of `a > 100`, or `a > 99` instead of `a >= 100`. Consider things like page sizes, where the lines consisting of x header, y body, and z footer lines, you can apply the obfuscations independently to each of these and to their partial or total sums. These time-honoured techniques are especially effective in a program with two unrelated arrays that just accidentally happen to both have 100 elements. If the maintenance programmer has to change the length of one of them, he will have to decipher every use of the literal 100 in the program to determine which array it applies to. He is almost sure to make at least one error, hopefully one that won't show up for years later. @@ -751,9 +742,9 @@ myfunc(6291, 8)[Array]; Unfortunately, these techniques can only be used in native C classes, not Java. -#### L o n g   L i n e s +#### L o n g L i n e s -Try to pack as much as possible into a single line. This saves the overhead of temporary variables, and makes source files shorter by eliminating new line characters and white space. Tip: remove all white space around operators. Good programmers can often hit the 255 character line length limit imposed by some editors. The bonus of long lines is that programmers who cannot read 6 point type must scroll to view them. +Try to pack as much as possible into a single line. This saves the overhead of temporary variables, and makes source files shorter by eliminating new line characters and white space. Tip: remove all white space around operators. Good programmers can often hit the 255 character line length limit imposed by some editors. The bonus of long lines is that programmers who cannot read 6 point types must scroll to view them. #### Exceptions @@ -765,17 +756,17 @@ Use exceptions for non-exceptional conditions. Routinely terminate loops with an #### Use threads With Abandon -title says it all. +Title says it all. #### Lawyer Code Follow the language lawyer discussions in the newsgroups about what various bits of tricky code should do e.g. `a=a++;` or `f(a++,a++);` then sprinkle your code liberally with the examples. In C, the effects of pre/post decrement code such as ```c -*++b ? (*++b + *(b-1)) 0 +*++b ? (*++b + *(b-1)) : 0 ``` -are not defined by the language spec. Every compiler is free to evaluate in a different order. This makes them doubly deadly. Similarly, take advantage of the complex tokenising rules of C and Java by removing all spaces. +are not defined by the language spec. Every compiler is free to evaluate in a different order. This makes them doubly deadly. Similarly, take advantage of the complex tokenizing rules of C and Java by removing all spaces. #### Early Returns @@ -799,7 +790,7 @@ If you need several variables of a given type, just define an array of them, the #### Never Beautify -Never use an automated source code tidier (beautifier) to keep your code aligned. Lobby to have them banned them from your company on the grounds they create false deltas in PVCS/CVS (version control tracking) or that every programmer should have his own indenting style held forever sacrosanct for any module he wrote. Insist that other programmers observe those idiosyncratic conventions in "his " modules. Banning beautifiers is quite easy, even though they save the millions of keystrokes doing manual alignment and days wasted misinterpreting poorly aligned code. Just insist that everyone use the **same** tidied format, not just for storing in the common repository, but also while they are editing. This starts an RWAR and the boss, to keep the peace, will ban automated tidying. Without automated tidying, you are now free to _accidentally_ misalign the code to give the optical illusion that bodies of loops and ifs are longer or shorter than they really are, or that else clauses match a different if than they really do. e.g. +Never use an automated source code tidier (beautifier) to keep your code aligned. Lobby to have them banned from your company on the grounds they create false deltas in PVCS/CVS (version control tracking) or that every programmer should have his own indenting style held forever sacrosanct for any module he wrote. Insist that other programmers observe those idiosyncratic conventions in "his " modules. Banning beautifiers is quite easy, even though they save the millions of keystrokes doing manual alignment and days wasted misinterpreting poorly aligned code. Just insist that everyone use the **same** tidied format, not just for storing in the common repository, but also while they are editing. This starts an RWAR and the boss, to keep the peace, will ban automated tidying. Without automated tidying, you are now free to _accidentally_ misalign the code to give the optical illusion that bodies of loops and ifs are longer or shorter than they really are, or that else clauses match a different if than they really do. e.g. ```c if(a) @@ -813,7 +804,7 @@ It offers great opportunities for obfuscation. The key technique is to nest macr #### Exploit Schizophrenia -Java is schizophrenic about array declarations. You can do them the old C, way `String x[]`, (which uses mixed pre-postfix notation) or the new way `String[] x`, which uses pure prefix notation. If you want to really confuse people, mix the notationse.g. +Java is schizophrenic about array declarations. You can do them the old C, way `String x[]`, (which uses mixed pre-postfix notation) or the new way `String[] x`, which uses pure prefix notation. If you want to really confuse people, mix the notations e.g. ```java byte[ ] rowvector, colvector , matrix[ ]; @@ -851,7 +842,7 @@ if ( function_A() == OK ) #### Pseudo C -The real reason for `#define` was to help programmers who are familiar with another programming language to switch to C. Maybe you will find declarations like `#define begin { " or " #define end }` useful to write more interesting code. +The real reason for `#define` was to help programmers who are familiar with another programming language to switch to C. Maybe you will find declarations like `#define begin {` or `#define end }` useful to write more interesting code. #### Confounding Imports @@ -972,7 +963,7 @@ Computer languages are gradually evolving to become more fool proof. Using state #### FØRTRAN -Write all your code in FORTRAN. If your boss ask why, you can reply that there are lots of very useful libraries that you can use thus saving time. However the chances of writing maintainable code in FORTRAN are zero, and therefore following the unmaintainable coding guidelines is a lot easier. +Write all your code in FORTRAN. If your boss asks why, you can reply that there are lots of very useful libraries that you can use thus saving time. However the chances of writing maintainable code in FORTRAN are zero, and therefore following the unmaintainable coding guidelines is a lot easier. #### Avoid Ada @@ -1011,7 +1002,7 @@ If your boss thinks that his or her 20 year old FORTRAN experience is an excelle #### Subvert The Help Desk -One way to help ensure the code is full of bugs is to ensure the maintenance programmers never hear about them. This requires subverting the help desk. Never answer the phone. Use an automated voice that says "thank you for calling the helpline. To reach a real person press "1" or leave a voice mail wait for the tone". Email help requests should be ignored other than to assign them a tracking number. The standard response to any problem is " I think your account is locked out. The person able to authorise reinstatement is not available just now." +One way to help ensure the code is full of bugs is to ensure the maintenance programmers never hear about them. This requires subverting the help desk. Never answer the phone. Use an automated voice that says "thank you for calling the helpline. To reach a real person press "1" or leave a voicemail wait for the tone". Email help requests should be ignored other than to assign them a tracking number. The standard response to any problem is " I think your account is locked out. The person able to authorise reinstatement is not available just now." #### Keep Your Mouth Shut @@ -1019,7 +1010,7 @@ Be never vigilant of the next Y2K. If you ever spot something that could sneak u #### Baffle 'Em With Bullshit -Subtlety is a wonderful thing, although sometimes a sledge-hammer is more subtle than other tools. So, a refinement on misleading comments create classes with names like `FooFactory` containing comments with references to the GoF creational patterns (ideally with http links to bogus UML design documents) that have nothing to do with object creation. Play off the maintainer's delusions of competence. More subtly, create Java classes with protected constructors and methods like `Foo f = Foo.newInstance()` that return actual **new instances**, rather than the expected singleton. The opportunities for side-effects are endless. +Subtlety is a wonderful thing, although sometimes a sledge-hammer is more subtle than other tools. So, a refinement on misleading comments creates classes with names like `FooFactory` containing comments with references to the GoF creational patterns (ideally with http links to bogus UML design documents) that have nothing to do with object creation. Play off the maintainer's delusions of competence. More subtly, create Java classes with protected constructors and methods like `Foo f = Foo.newInstance()` that return actual **new instances**, rather than the expected singleton. The opportunities for side-effects are endless. #### Book Of The Month Club @@ -1084,7 +1075,7 @@ and left,5 = "without" #### Delphi/Pascal Only -Don't use functions and procedures. Use the label/goto statements then jump around a lot inside your code using this. It'll drive 'em mad trying to trace through this. Another idea, is just to use this for the hang of it and scramble your code up jumping to and fro in some haphazard fashion. +Don't use functions and procedures. Use the label/goto statements then jump around a lot inside your code using this. It'll drive 'em mad trying to trace through this. Another idea is just to use this for the hang of it and scramble your code up jumping to and fro in some haphazard fashion. #### Perl @@ -1117,7 +1108,7 @@ LOCAL lcx lcx = TYPE('somevariable') ``` -The value of lcx is now `'L'` or logical. It is further defined the value of `FALSE`. Just imagine the power of this in writing unmaintainable code. +The value of lcx is now `'L'` or logical. It further defined the value of `FALSE`. Just imagine the power of this in writing unmaintainable code. ```foxpro LOCAL lc_one, lc_two, lc_three... , lc_n @@ -1180,7 +1171,7 @@ Stick with what you know and travel light; if you only carry a hammer then all p #### Standards Schmandards -Whenever possible ignore the coding standards currently in use by thousands of developers in your project's target language and environment. For example insist on STL style coding standards when writing an MFC based application. +Whenever possible ignore the coding standards currently in use by thousands of developers in your project's target language and environment. For example, insist on STL style coding standards when writing an MFC based application. #### Reverse the Usual True False Convention @@ -1204,7 +1195,7 @@ someone is bound to "correct" the apparent redundancy, and use var elsewhere in if ( var ) ``` -Another technique is to make `TRUE` and `FALSE` have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called `TRUE`. Programmers might be more suspicious you are up to no good since there is a built-in literal true in Java. +Another technique is to make `TRUE` and `FALSE` have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called `TRUE`. Programmers might be more suspicious you are up to no good since there is a built-in literal `true` in Java. #### Third Party Libraries @@ -1220,11 +1211,11 @@ Make it so elaborate that no maintainer could ever get any of his or her fixes t #### More Fun With Make -Have the makefile-generated-batch-file copy source files from multiple directories with undocumented overrwrite rules. This permits code branching without the need for any fancy source code control system, and stops your successors ever finding out which version of `DoUsefulWork()` is the one they should edit. +Have the makefile-generated-batch-file copy source files from multiple directories with undocumented overwrite rules. This permits code branching without the need for any fancy source code control system, and stops your successors ever finding out which version of `DoUsefulWork()` is the one they should edit. #### Collect Coding Standards -Find all the tips you can on writing maintainable code such as the [Square Box Suggestions](http://www.squarebox.co.uk/javatips.html) and flagrantly violate them. +Find all the tips you can on writing maintainable code such as the [Square Box Suggestions](http://www.squarebox.co.uk/download/javatips.html) and flagrantly violate them. #### IDE, Not Me! @@ -1296,7 +1287,7 @@ void* Realocate(void*buf, int os, int ns) * Reinvent simple functions which are part of the standard libraries. * The word _Realocate_ is not spelled correctly. Never underestimate the power of creative spelling. -* Make a temporary copy of input buffer for no real reason. +* Make a temporary copy of an input buffer for no real reason. * Cast things for no reason. `memcpy()` takes `(void*)`, so cast our pointers even though they're already `(void*)`. Bonus for the fact that you could pass anything anyway. * Never bothered to free temp. This will cause a slow memory leak, that may not show up until the program has been running for days. * Copy more than necessary from the buffer just in case. This will only cause a core dump on Unix, not Windows. @@ -1315,13 +1306,13 @@ i = i; It almost goes without saying that the larger a function is, the better it is. And the more jumps and GOTOs the better. That way, any change must be analysed through many scenarios. It snarls the maintenance programmer in the spaghettiness of it all. And if the function is truly gargantuan, it becomes the Godzilla of the maintenance programmers, stomping them mercilessly to the ground before they have an idea of what's happened. -#### A Picture is a 1000 Words; A Function is 1000 Lines +#### A Picture is a 1000 Words; A Function is a 1000 Lines Make the body of every method as long as possible - hopefully you never write any methods or functions with fewer than a thousand lines of code, deeply nested, of course. #### One Missing File -Make sure that one or more critical files is missing. This is best done with includes of includes. For example, in your main module, you have +Make sure that one or more critical files are missing. This is best done with includes of includes. For example, in your main module, you have ```c #include @@ -1333,7 +1324,7 @@ Make sure that one or more critical files is missing. This is best done with inc #include "a:\\refcode.h" ``` -and `refcode.h` is no where to be found. +and `refcode.h` is nowhere to be found. #### Write Everywhere, Read Nowhere @@ -1343,7 +1334,7 @@ At least one variable should be set everywhere and used almost nowhere. Unfortun The people who design languages are the people who write the compilers and system classes. Quite naturally they design to make their work easy and mathematically elegant. However, there are 10,000 maintenance programmers to every compiler writer. The grunt maintenance programmers have absolutely no say in the design of languages. Yet the total amount of code they write dwarfs the code in the compilers. -An example of the result of this sort of elitist thinking is the JDBC interface. It makes life easy for the JDBC implementor, but a nightmare for the maintenance programmer. It is far **clumsier** than the FORTRAN interface that came out with SQL three decades ago. +An example of the result of this sort of elitist thinking is the JDBC interface. It makes life easy for the JDBC implementer, but a nightmare for the maintenance programmer. It is far **clumsier** than the FORTRAN interface that came out with SQL three decades ago. Maintenance programmers, if somebody ever consulted them, would demand ways to hide the housekeeping details so they could see the forest for the trees. They would demand all sorts of shortcuts so they would not have to type so much and so they could see more of the program at once on the screen. They would complain loudly about the myriad petty time-wasting tasks the compilers demand of them.