New build path variable
[freeradius.git] / doc / coding-methods.rst
1 Helpful coding methods
2 ======================
3
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.
8
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.
12
13
14
15 1. Comment your code.
16
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.
19
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
22     that.
23
24
25 2. Give things reasonable names.
26
27    Variables and functions should have names.  Calling them 'x',
28    'xx', and 'xxx' makes your life hell.  Even 'foo' and 'i' are
29    problematic.
30
31
32 3. Check input parameters in the functions you write.
33
34    Your function CANNOT do anything right if the user passed in
35    garbage, and you were too lazy to check for garbage input.
36
37    assert() is ugly.  Use it.
38
39    GIGO is wrong.  If your function gets garbage input, it
40    should complain loudly and with great descriptiveness.
41
42
43 4. Write useful error messages.
44
45    "Function failed" is useless as an error message.  It makes
46    debugging the code impossible without source-level instrumentation.
47
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.
51
52
53 5. Check error conditions from the functions you call.
54
55    Your function CANNOT do anything right if you called another
56    function, and they gave you garbage output.
57
58    One of the most common mistakes is::
59
60     fp = fopen(...);
61     fgetc(fp);                 /* core dumps! */
62
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.
66
67
68 6. Core dumps are for weenies.
69
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.
73
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...)
78
79
80 7. Initialize your variables.
81
82    memset() is your friend.  'ptr = NULL' is nice, too.
83
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.
87
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.
90
91
92 8. Don't allow buffer over-runs.
93
94    They're usually accidental, but they cause core dumps.
95    strcpy() and strcat() are ugly.  Use them under duress.
96
97    sizeof() is your friend.
98
99
100 9. 'const' is your friend.
101
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.
105
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.
109
110
111 10. Use C compiler warnings.
112
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.
116
117     Getting error messages at compile time is much preferable to
118     getting core dumps at run time.  See #7.
119
120     Notice that the C compiler error messages are helpful?  You should
121     write error messages like this, too.  See #4.
122
123
124 11. Avoid UNIXisms and ASCIIisms and visualisms.
125
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.
128
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 :) ).
133
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,
138     and numbers.
139
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
143     up.
144
145
146 12. Make conditionals explicit.
147
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.
153
154
155 13. Test your code.
156
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.
159
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
162     easier to debug.