comparison doc/devel/style.txt @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children 12171da8943f
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 Style guidelines for AnaGram source
2 -----------------------------------
3
4 Purpose:
5
6 These guidelines are *guidelines*, not commandments. Legibility and
7 maintainability are more important than mindless adherence to
8 regulations.
9
10 Note: patches that reindent or reformat will be rejected. Patches
11 whose only purpose is to reindent or reformat will be rejected
12 extra-fast. If you think a section of code needs reformatting,
13 write a message saying so and explain your reasoning. Illegibility
14 and violation of the principle of least surprise are good reasons.
15 Lack of strict conformance to these guidelines is not.
16
17 Note: some source files have DOS-style end of line (CR/LF) and
18 others have Unix-style end of line (just LF) - for the most part
19 this should be transparent. So leave things the way they are in
20 this regard.
21
22 Basic layout guidelines, in order of decreasing generality:
23
24 - 2-space indent.
25 - Lines do not exceed 79 columns.
26 - Don't indent preprocessor directives.
27 - In a multi-line /* */ comment, the beginning and ending tokens
28 get their own lines, and all the stars should line up.
29 - Left braces go at the end of the line.
30 - Right braces get their own line.
31 - 'else' starts a new line.
32 - Use braces with if, else, while, do/while, and for.
33 - If violating the previous rule, always put the subordinate
34 statement on the same line.
35 - Violate said rule for conciseness only when:
36 - a single if (no else) has a very short conditional and a
37 very short subordinate statement;
38 - a while statement ditto;
39 - or a for statement has no body.
40 - Never violate said rule for a do/while statement.
41 - Put the while part of a do/while statement on the same line as
42 the closing brace, to keep them from getting separated.
43 - Switch case labels should be indented two spaces, and code
44 indented two spaces further.
45 - Each switch case label should get its own line.
46 - Switch code should not be on the same line as a switch case.
47 - Condensed switches (one line total per case) should only be used
48 if all or nearly all the switch can be formatted thus and some
49 benefit to legibility accrues.
50 - Infinite loops should be written as "while (1)", not "for (;;)".
51
52 Please do not:
53
54 - Misgroup tokens when declaring pointers. "char* s" is wrong. It
55 should be "char *s".
56 - Write your comparisons backwards. "if (0 == x)" is really
57 unnatural to read.
58 - Leave off the space after while, for, and if, or, conversely,
59 insert a space between a function name and its arguments. while,
60 for, and if are not functions.
61 - Use gratuitous parentheses with return to make it look like a
62 function call.
63
64
65 Include files:
66
67 - Include files should be grouped in this order:
68 - standard C includes
69 - OS, compiler, or GUI-specific includes
70 - AG's own includes
71
72 - Within these groupings, headers should appear in alphabetical
73 order. (Why...? Why not?)
74
75 - Exceptions: any <sys/*.h> should come before other standard
76 headers. And if any <sys/*.h> are used, <sys/types.h> should come
77 first. Also, "pf.h" should be included after any standard headers.
78
79 - Further exceptions: AG's log header should come last, and should
80 be preceded by a commented-out "#define INCLUDE_LOGGING".
81 Examples abound.
82
83 - To the extent practical, don't use (even within AG_ON_UNIX)
84 header files that aren't standard or standardish Unix, or that
85 would require build-time tests in the configure script to make
86 work right.
87
88 - Each AG header file should be idempotent, that is, a source file
89 that just includes it should be compilable and its compilation
90 should not be affected by whether other headers have been
91 included or in what order.
92
93 - Each header should have an #ifndef guard in the standard form to
94 protect against repeated inclusion.
95
96 - Do not use the standard <assert.h> within AG - only use AG's own
97 "assert.h".
98
99
100 ifdefs:
101
102 - Use #ifdef AG_ON_UNIX and #ifdef AG_ON_WINDOWS for
103 platform-specific code. Don't use compiler ifdefs for this;
104 in the long run compilers are more portable than you think.
105
106 - Don't use #ifndef AG_ON_UNIX or #ifndef AG_ON_WINDOWS, unless
107 it's to issue a #error.
108
109 - Don't use #if defined() in place of #ifdef.
110
111 - Do mark #endifs with the symbol from their matching #ifdef,
112 #ifndef, or #if, unless that directive is only a few lines above
113 and easily recognizable.
114
115 - Use compiler-specific ifdefs only where you have to. If possible,
116 abstract the construct out to minimize the amount of conditional
117 code.
118
119 - If a compiler doesn't have a well-known, safe, and/or easily
120 recognizable symbol to #ifdef on, adjust the makefiles to set
121 one when that compiler is used, rather than litter the code with
122 possibly flaky ifdefs.
123
124 - Don't use processor-specific ifdefs. Write portable code.
125
126
127 C++ language restrictions:
128
129 - Do not use STL headers.
130
131 - Do not use << >> operators for I/O.
132
133 - Declare functions with no arguments as explicitly taking void,
134 like you would in C.
135
136 - Don't do wild things with templates.
137
138 - Don't do "for (int i=0; ...)" - we have a compiler that uses the
139 really old scoping semantics for this.
140
141 - Use your common sense. Neither the language nor compiler has any.
142
143
144 Portability concerns:
145
146 - When using fopen, always use "b" with binary files. Don't use "t"
147 for text files, as this is nonstandard and at least one Windows
148 compiler's library objects to it.
149
150 - When using open(), always use either O_BINARY or O_TEXT.
151
152 - The proper type associated with strlen() and sizeof() is size_t.
153 Don't use "int" or "unsigned". The signed return value of Unix
154 read() and write() has type "ssize_t". Cast that back to size_t
155 after checking it for being an error return.
156
157 - When using printf, don't use the C99 %-specifier for size_t;
158 always cast size_t to unsigned long and print with %lu.
159
160 - Assume that time_t may be 64 bits wide, even on 32-bit platforms.
161 If you need to print one literally, use %lld and cast to long
162 long.
163
164 - Don't assume that all pointers are the same size, or that
165 pointers are the same size as either int or long.
166
167 - In the mainline AG code avoid using anything that might be
168 locale-dependent, as the user interface might have set some crazy
169 locale.
170
171 - Don't blindly slice filename strings using path separator
172 characters. Use appropriate functions instead. And avoid slicing
173 filename strings unless necessary.
174
175 - Always pull the name component out of a pathname before looking
176 for any filename suffix. Otherwise you lose on names like
177 "foo.d/bar".
178
179
180 Robustness concerns:
181
182 - If you mean to fall through the bottom of a switch case (one that
183 has code) put /* FALLTHROUGH */ there.
184
185 - If you have virtual functions in a class, declare the destructor
186 virtual too.
187
188 - If you have functions in a class that are virtual because they're
189 declared that way by a base (ancestor) class, declare them
190 explicitly virtual yourself too.
191
192 - Don't define virtual functions inline, unless there's no other
193 practical place to put the definition.
194
195 - Use parentheses when mixing && and ||, or &, |, and ^, or in
196 other cases where operator precedence is easily confused.
197
198 - If you need an assignment inside a conditional, wrap the
199 assignment in parentheses and an explicit comparison. (Not just
200 extra parentheses.) But don't do this unless there's a reason for
201 it.
202
203 - If using qsort() from <stdlib.h>, be sure your compare function
204 only returns 0 for identical objects. If the objects aren't
205 identical, always pick *something* to distinguish by, so the sort
206 is deterministic.
207
208
209 Idioms:
210
211 - YES: if (!strcmp(a, b))
212 NO: if (strcmp(a, b) == 0)
213
214 - YES: if (strcmp(a, b) != 0)
215 NO: if (strcmp(a, b))
216