4 The following is a short set of guidelines to follow while
5 programming. It does not address coding styles, function naming
6 methods, or debugging methods. Rather, it describes the processes
7 which SHOULD go on in the programmers mind, while he is programming.
9 Coding standards apply to function names, the look of the code, and
10 coding consistency. Coding methods apply to the daily practices used
11 by the programmer to write code.
17 If you don't, you'll be forced to debug it 6 months later, when
18 you have no clue as to what it's doing.
20 If someone REALLY hates you, you'll be forced to debug
21 un-commented code that someone else wrote. You don't want to do
25 2. Give things reasonable names.
27 Variables and functions should have names. Calling them 'x',
28 'xx', and 'xxx' makes your life hell. Even 'foo' and 'i' are
32 3. Check input parameters in the functions you write.
34 Your function CANNOT do anything right if the user passed in
35 garbage, and you were too lazy to check for garbage input.
37 assert() is ugly. Use it.
39 GIGO is wrong. If your function gets garbage input, it
40 should complain loudly and with great descriptiveness.
43 4. Write useful error messages.
45 "Function failed" is useless as an error message. It makes
46 debugging the code impossible without source-level instrumentation.
48 If you're going to instrument the code at source level for error
49 messages, leave the error messages there, so the next sucker won't
50 have to do the same work all over again.
53 5. Check error conditions from the functions you call.
55 Your function CANNOT do anything right if you called another
56 function, and they gave you garbage output.
58 One of the most common mistakes is::
61 fgetc(fp); /* core dumps! */
63 If the programmer had bothered to check for a NULL fp (error
64 condition), then he could have produced a DESCRIPTIVE error
65 message, instead of having his program core dump.
68 6. Core dumps are for weenies.
70 If your program core dumps accidentally, you're a bad programmer.
71 You don't know what your program is doing, or what it's supposed
72 to be doing when anything goes wrong.
74 If it hits an assert() and calls abort(), you're a genius. You've
75 thought ahead to what MIGHT go wrong, and put in an assertion to
76 ensure that it fails in a KNOWN MANNER when something DOES go
77 wrong. (As it usually does...)
80 7. Initialize your variables.
82 memset() is your friend. 'ptr = NULL' is nice, too.
84 Having variables containing garbage values makes it easy for the
85 code to do garbage things. The contents of local variables are
86 inputs to your function. See #3.
88 It's also nearly impossible for you to debug any problems, as you
89 can't tell the variables with garbage values from the real ones.
92 8. Don't allow buffer over-runs.
94 They're usually accidental, but they cause core dumps.
95 strcpy() and strcat() are ugly. Use them under duress.
97 sizeof() is your friend.
100 9. 'const' is your friend.
102 If you don't mean to modify an input structure to your function,
103 declare it 'const'. Declare string constants 'const'. It can't
104 hurt, and it allows more errors to be found at compile time.
106 Use 'const' everywhere. Once you throw a few into your code, and
107 have it save you from stupid bugs, you'll blindly throw in 'const'
108 everywhere. It's a life-saver.
111 10. Use C compiler warnings.
113 Turn on all of the C compiler warnings possible. You might have
114 to turn some off due to broken system header files, though. But
115 the more warnings the merrier.
117 Getting error messages at compile time is much preferable to
118 getting core dumps at run time. See #7.
120 Notice that the C compiler error messages are helpful? You should
121 write error messages like this, too. See #4.
124 11. Avoid UNIXisms and ASCIIisms and visualisms.
126 You don't know under what system someone will try to run your code.
127 Don't demand that others use the same OS or character set as you use.
129 Never assign numbers to pointers. If foo is a char*, and you want it
130 to be be null, assign NULL, not 0. The zeroth location is perfectly
131 as addressable as any other on plenty of OSes. Not all the world
132 runs on Unix (though it should :) ).
134 Another common mistake is to assume that the zeroth character in the
135 character set is the string terminator. Instead of terminating a
136 string with 0, use '\0', which is always right. Similarly, memset()
137 with the appropriate value: NULL, '\0', or 0 for pointers, chars,
140 Don't put tabs in string constants, either. Always use '\t' to
141 represent a tab, instead of ASCII 9. Literal tabs are presented to
142 readers of your code as arbitrary whitespace, and it's easy to mess
146 12. Make conditionals explicit.
148 Though it's legal to test "if (foo){}", if you test against the
149 appropriate value (like NULL or '\0'), your code is prettier and
150 easier for others to read without having to eyeball your prototypes
151 continuously to figure out what you're doing (especially if your
152 variables aren't well-named). See #2.
157 Even Donald Knuth writes buggy code. You'll never find all of the
158 bugs in your code unless you write a test program for it.
160 This also means that you'll have to write your code so that it
161 will be easily testable. As a result, it will look better, and be