Skip to main content
  1. Posts/

Programming-Rules-of-Thumb

1752 words·9 mins

Programming-Rules-of-Thumb #

Programming Rules of Thumb #

Created: December 4, 2019 6:22 PM Tags: Programming URL: https://holub.com/goodies/rules.html The following list is essentially the table of contents for my book Enough Rope to Shoot Yourself in the Foot (McGraw-Hill, 1995). The book was written with C/C++ in mind, but most of the rules apply to programming in general and OO programming in other languages (such as Java) in particular. 1 The essentials of programming: No surprises, minimize coupling, and maximize cohesion 2 Stamp out the demons of complexity (Part 1) 2.1 Don’t solve problems that don’t exist 2.2 Solve the specific problem, not the general case 3 A user interface should not look like a computer program (the transparency principle) 4 Don’t confuse ease of learning with ease of use 5 Productivity can be measured in the number of keystrokes 6 If you can’t say it in English, you can’t say it in C/C++ 6.1 Do the comments first 7 Read code 7.1 There’s no room for prima donnas in a contemporary programming shop 8 Decompose complex problems into smaller tasks 9 Use the whole language (Use the appropriate tool for the job) 10 A problem must be thought through before it can be solved 11 Computer programming is a service industry 12 Involve users in the development process 13 The customer is always right 14 Small is Beautiful. (Big == slow)

General Development Issues #

15 First, do no harm 16 Edit your code 17 A program must be written at least twice 18 You can’t measure productivity by volume 19 You can’t program in isolation 20 Goof off 21 Write code with maintenance in mind�the maintenance programmer is you 21.1 Efficiency is often a bugaboo

Formatting and Documentation #

22 Uncommented code has no value 23 Put the code and the documentation in the same place 24 Comments should be sentences 25 Run your code through a spelling checker 26 A comment shouldn’t restate the obvious 27 A comment should provide only information needed for maintenance 28 Comments should be in blocks 29 Comments should align vertically 30 Use neat columns as much as possible 31 Don’t put comments between the function name and the open brace 32 Mark the ends of long compound statements with something reasonable 33 Put only one statement per line 34 Put argument names in function prototypes 35 Use a �predicate� form to split up long expressions 36 A subroutine should fit on a screen 37 All code should be printable 38 Use lines of dashes for visual separation between subroutines 39 White space is one of the most effective comments 40 Use four-space indents 41 Indent statements associated with a flow-control statement 41.1.Comments should be at the same indent level as the surrounding code 42 Align braces vertically at the outer level 43 Use braces when more than one line is present under a flow-control statement

Names and Identifiers #

44 Names should be common English words, descriptive of what the function, argument, or variable does 44.1.Do not clutter names with gibberish 45 Macro names should be ENTIRELY_CAPITALIZED 45.1 Do not capitalize members of an enum 45.2 Do not capitalize type names created with a typedef 46 Avoid the ANSI C name space 47 Avoid the Microsoft name space 48 Avoid unnecessary symbols 49 Symbolic constants for Boolean values are rarely necessary

Rules for General Programming #

50 Don’t confuse familiarity with readability 51 A function should do only one thing 52 Too many levels of abstraction or encapsulation are as bad as too few 53 A function should be called more than once, but� 53.1 Code used more than once should be put into a function 54 A function should have only one exit point 54.1 Always put a return at the outer level 55 Avoid duplication of effort 56 Don’t corrupt the global name space 56.1 Avoid global symbols 56.2 Never require initialization of a global variable to call a function 56.2.1 Make locals static in recursive functions if the value doesn’t span a recursive call 56.3 Use instance counts in place of initialization functions 56.4 If an if ends in return, don’t use else 57 Put the shortest clause of an if/else on top 58 Try to move errors from run time to compile time 59 Use C function pointers as selectors 60 Avoid do/while loops 60.1 Never use a do/while for a forever loop 61 Counting loops should count down if possible 62 Don’t do the same thing in two ways at the same time 63 Use for if any two of an initialization, test, or increment are present 64 If it doesn’t appear in the test, it shouldn’t appear in the other parts of for statement 65 Assume that things will go wrong 66 Computers do not know mathematics 66.1 Expect the impossible 66.2 Always check error-return codes 67 Avoid explicit temporary variables 68 No magic numbers 69 Make no assumptions about sizes 70 Beware of casts (C issues) 71 Handle special cases directly 72 Don’t try to make lint happy 73 Put memory allocation and deallocation code in the same place 74 Heap memory is expensive 75 Test routines should not be interactive 76 An error message should tell the user what’s right 77 Don’t print error messages if an error is recoverable 78 Don’t use system-dependent functions for error messages

The Preprocessor #

79 Everything in a .h file should be used in at least two .c files 80 Use nested #includes 81 You should always be able to replace a macro with a function 81.1 ?
is not the same as if/else 81.2 Parenthesize macro bodies and arguments 82 enum and const are better than a macro 83 A parameterized-macro argument should not appear more than once on the right-hand side 83.1 Never use macros for character constants 84 When all else fails, use the preprocessor

85 Stamp out the demons of complexity (Part 2) 85.1 Eliminate clutter.

OO Programming/Design (C++ and Java) #

90 Object-oriented and �structured" designs don’t mix 90.1 If it’s not object-oriented, use C 91 Expect to spend more time in design and less in development 92 C++ class libraries usually can’t be used in a naive way 93 Use checklists 94 Messages should exercise capabilities, not request information 95 You usually cannot convert an existing structured program to object-oriented 96 A derived class object is a base-class object 97 Derivation is the process of adding member data and methods 98 Design the objects first 99 Design the hierarchy next, from the bottom up 99.1 Base classes should have more than one derived class 100 The capabilities defined in the base class should be used by all derived classes 101 C++ is not Smalltalk�avoid a common object class 102 Mix-ins shouldn’t derive from anything in C++, in Java there’s no problem if you follow the next rule: 103 Mix-ins should be C++ virtual base classes (in Java they should be interfaces) 104 Initialize virtual base classes with the default constructor 105 Derivation is not appropriate if you never send a base-class message to a derived-class object 106 Choose containment over derivation whenever possible 107 Use private base classes only when you must provide virtual overrides (C++ only) 108 Design the data structures last 109 All data in a class definition must be private 110 Never provide public access to private data 110.1 Do not use get/set functions 111 Give up on C idioms when coding in C++ 112 Design with derivation in mind 112.1 A member function should usually use the private data of a class 113 Use const (final in Java) 114 Use struct only if everything’s public and there are no member functions (C++ only) 115 Don’t put function bodies into class definitions (C++ only) 116 Avoid function overloads and default arguments 117 Avoid friend classes (in Java, don’t use package access.) 118 Inheritance is a form of coupling 119 Don’t corrupt the global name space

C++ Rules #

References #

120 Reference arguments should always be const 121 Never use references as outputs, use pointers 122 Do not return references (or pointers) to local variables 123 Do not return references to memory that came from new

Constructors, Destructors, and operator=() #

124 Operator=() should return a const reference 125 Assignment to self must work 126 Classes having pointer members should always define a copy constructor and operator=() 127 If you can access an object, it has been initialized 128 Use member-initialization lists 129 Assume that members and base classes are initialized in random order 130 Copy constructors must use member initialization lists 131 Derived classes should usually define a copy constructor and operator=() 132 Constructors not suitable for type conversion should have two or more arguments 133 Use instance counts for class-level initialization 134 Avoid two-part initialization 135 C++ wrappers around existing interfaces rarely work well

Virtual Functions #

136 Virtual functions are those functions that you can’t write at the base-class level 137 A virtual function isn’t virtual when called from a constructor or destructor 138 Do not call pure virtual functions from constructors 139 Destructors should always be virtual 140 Base-class functions that have the same name as derived-class functions generally should be virtual 141 Don’t make a function virtual unless you want the derived class to get control of it 142 protected functions should usually be virtual 143 Beware of casts: C++ issues 144 Don’t call constructors from operator=()

Operator Overloads #

145 An operator is an abbreviation (no surprises) 146 Use operator overloads only to define operations for which there is a C analog (no surprises) 147 Once you overload an operation, you must overload all similar operations 148 Operator overloads should work exactly like they would in C 149 It’s best for a binary-operator overload to be an inline alias for a cast 150 Don’t go bonkers with type-conversion operators 151 Do all type conversions with constructors if possible

Memory Management #

152 Use new/delete rather than malloc()/free() 153 All memory allocated in a constructor should be freed in the destructor 154 Local overloads of new and delete are dangerous

Templates #

155 Use inline function templates instead of parameterized macros 156 Always be aware of the size of the expanded template 157 Class templates should usually define derived classes 158 Templates do not replace derivation; they automate it

Exceptions #

159 Intend for exceptions not to be caught 160 Throw error objects when possible 161 Throwing exceptions from constructors is tricky