VirtualBox

source: vbox/trunk/doc/VBox-CodingGuidelines.cpp@ 7200

Last change on this file since 7200 was 6303, checked in by vboxsync, 17 years ago

Some updates .

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.0 KB
Line 
1/** @file
2 *
3 * VBox - Coding Guidelines.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * innotek GmbH confidential
10 * All rights reserved
11 */
12
13/** @page pg_vbox_guideline VBox Coding Guidelines
14 *
15 * The VBox Coding guidelines are followed by all of VBox with the exception of
16 * the GUI and qemu. The GUI is using something close to the Qt style. Qemu is
17 * using whatever the frenchman does.
18 *
19 * There are a few compulsory rules and a bunch of optional ones. The following
20 * sections will describe these in details. In addition there is a section of
21 * Subversion 'rules'.
22 *
23 *
24 *
25 * @section sec_vbox_guideline_compulsory Compulsory
26 *
27 *
28 * - Use RT and VBOX types.
29 *
30 * - Use Runtime functions.
31 *
32 * - Use the standard bool, uintptr_t, intptr_t and [u]int[1-9+]_t types.
33 *
34 * - Avoid using plain unsigned and int.
35 *
36 * - Use static wherever possible. This makes the namespace less polluted
37 * and avoid nasty name clash problems which can occure, especially on
38 * Unix like systems. (1)
39 *
40 * - Public names are on the form Domain[Subdomain[]]Method using mixed
41 * casing to mark the words. The main domain is all uppercase.
42 * (Think like java, mapping domain and subdomain to packages/classes.)
43 *
44 * - Public names are always declared using the appropriate DECL macro. (2)
45 *
46 * - Internal names starts with a lowercased main domain.
47 *
48 * - Defines are all uppercase and separate words with underscore.
49 * This applies to enum values too.
50 *
51 * - Typedefs are all uppercase and contain no underscores to distinguish
52 * them from defines.
53 *
54 * - Pointer typedefs start with 'P'. If pointer to const value then 'PC'.
55 *
56 * - Function typedefs start with 'FN'. If pointer to one then 'PFN'.
57 *
58 * - All files are case sensitive.
59 *
60 * - Slashes are unix slashes ('/') runtime converts when necessary.
61 *
62 * - char strings are UTF-8.
63 *
64 * - All functions returns VBox status codes. There are three general exceptions
65 * from this:
66 * -# Predicate functions. These are function which are boolean in nature
67 * and usage. They return bool. The function name will include
68 * 'Has', 'Is' or similar.
69 * -# Functions which by nature cannot possibly fail.
70 * These return void.
71 * -# "Get"-functions which return what they ask for.
72 * A get function becomes a "Query" function if there is any
73 * doubt about getting what is ask for.
74 *
75 * - VBox status codes have three subdivisions:
76 * -# Errors, which are VERR_ prefixed and negative.
77 * -# Warnings, which are VWRN_ prefixed and positive.
78 * -# Informational, which are VINF_ prefixed and positive.
79 *
80 * - Platform/OS operation are generalized and put in the IPRT.
81 *
82 * - Other useful constructs are also put in the IPRT.
83 *
84 * - The code shall not cause compiler warnings. Check this with on ALL
85 * the platforms.
86 *
87 * - All files have file headers with $Id and a file tag which describes
88 * the file in a sentence or two.
89 * Note: Remember to enable keyword expansion when adding files to svn.
90 *
91 * - All public functions are fully documented in Doxygen style using the
92 * javadoc dialect (using the 'at' insdead of the 'slash' as commandprefix.)
93 *
94 * - All structures in header files are described, including all of their
95 * members.
96 *
97 * - All modules have a documentation 'page' in the main source file which
98 * describes the intent and actual implementation.
99 *
100 * - Code which is doing things that are not immediatly comprehendable
101 * shall include explanatory comments!
102 *
103 * - Documentation and comments are kept up to date.
104 *
105 * - Headers in /include/VBox shall not contain any slash-slash C++ comments,
106 * only ansi C comments!
107 *
108 *
109 * (1) It is common practice on Unix to have a single symbol namespace for an
110 * entire process. If one is careless symbols might be resolved in a
111 * different way that one expects, leading to weird problems.
112 *
113 * (2) This is common practice among most projects dealing with modules in
114 * shared libraries. The Windows / PE __declspect(import) and
115 * __declspect(export) constructs are the main reason for this.
116 * OTH, we do perhaps have a bit too detailed graining of this in VMM...
117 *
118 *
119 *
120 * @subsection sec_vbox_guideline_compulsory_sub64 64-bit and 32-bit
121 *
122 * Here are some amendments which address 64-bit vs. 32-bit portability issues.
123 *
124 * Some facts first:
125 *
126 * - On 64-bit Windows the type long remains 32-bit. On nearly all other
127 * 64-bit platforms long is 64-bit.
128 *
129 * - On all 64-bit platforms we care about, int is 32-bit, short is 16 bit
130 * and char is 8-bit.
131 * (I don't know about any platforms yet where this isn't true.)
132 *
133 * - size_t, ssize_t, uintptr_t, ptrdiff_t and similar are all 64-bit on
134 * 64-bit platforms. (These are 32-bit on 32-bit platforms.)
135 *
136 * - There is no inline assembly support in the 64-bit Microsoft compilers.
137 *
138 *
139 * Now for the guidelines:
140 *
141 * - Never, ever, use int, long, ULONG, LONG, DWORD or similar to cast a
142 * pointer to integer. Use uintptr_t or intptr_t. If you have to use
143 * NT/Windows types, there is the choice of ULONG_PTR and DWORD_PTR.
144 *
145 * - RT_OS_WINDOWS is defined to indicate Windows. Do not use __WIN32__,
146 * __WIN64__ and __WIN__ because they are all deprecated and schedule
147 * for removal (if not removed already). Do not use the compiler
148 * defined _WIN32, _WIN64, or similar either. The bitness can be
149 * determined by testing ARCH_BITS.
150 * Example:
151 * @code
152 * #ifdef RT_OS_WINDOWS
153 * // call win32/64 api.
154 * #endif
155 * #ifdef RT_OS_WINDOWS
156 * # if ARCH_BITS == 64
157 * // call win64 api.
158 * # else // ARCH_BITS == 32
159 * // call win32 api.
160 * # endif // ARCH_BITS == 32
161 * #else // !RT_OS_WINDOWS
162 * // call posix api
163 * #endif // !RT_OS_WINDOWS
164 * @endcode
165 *
166 * - There are RT_OS_xxx defines for each OS, just like RT_OS_WINDOWS
167 * mentioned above. Use these defines instead of any predefined
168 * compiler stuff or defines from system headers.
169 *
170 * - RT_ARCH_X86 is defined when compiling for the x86 the architecture.
171 * Do not use __x86__, __X86__, __[Ii]386__, __[Ii]586__, or similar
172 * for this purpose.
173 *
174 * - RT_ARCH_AMD64 is defined when compiling for the AMD64 the architecture.
175 * Do not use __AMD64__, __amd64__ or __x64_86__.
176 *
177 * - Take care and use size_t when you have to, esp. when passing a pointer
178 * to a size_t as a parameter.
179 *
180 *
181 *
182 * @section sec_vbox_guideline_optional Optional
183 *
184 * First part is the actual coding style and all the prefixes the second part is
185 * the a bunch of good advice.
186 *
187 *
188 * @subsection sec_vbox_guideline_optional_layout The code layout
189 *
190 * - Curly brackets are not indented.
191 *
192 * - Space before the parenthesis when it comes after a C keyword.
193 *
194 * - No space between argument and parenthesis. Exception for complex
195 * expression.
196 * Example:
197 * @code
198 * if (PATMR3IsPatchGCAddr(pVM, GCPtr))
199 * @endcode
200 *
201 * - The else of an if is always first statement on a line. (No curly
202 * stuff before it!)
203 *
204 * - else and if goes on the same line if no curly stuff is needed around the if.
205 * Example:
206 * @code
207 * if (fFlags & MYFLAGS_1)
208 * fFlags &= ~MYFLAGS_10;
209 * else if (fFlags & MYFLAGS_2)
210 * {
211 * fFlags &= ~MYFLAGS_MASK;
212 * fFlags |= MYFLAGS_5;
213 * }
214 * else if (fFlags & MYFLAGS_3)
215 * @endcode
216 *
217 * - The case is indented from the switch.
218 *
219 * - If a case needs curly brackets they contain the entire case, are not
220 * indented from the case, and the break or return is placed inside them.
221 * Example:
222 * @code
223 * switch (pCur->eType)
224 * {
225 * case PGMMAPPINGTYPE_PAGETABLES:
226 * {
227 * unsigned iPDE = pCur->GCPtr >> PGDIR_SHIFT;
228 * unsigned iPT = (pCur->GCPtrEnd - pCur->GCPtr) >> PGDIR_SHIFT;
229 * while (iPT-- > 0)
230 * if (pPD->a[iPDE + iPT].n.u1Present)
231 * return VERR_HYPERVISOR_CONFLICT;
232 * break;
233 * }
234 * }
235 * @endcode
236 *
237 * - In a do while construction, the while is on the same line as the
238 * closing bracket if any are used.
239 * Example:
240 * @code
241 * do
242 * {
243 * stuff;
244 * i--;
245 * } while (i > 0);
246 * @endcode
247 *
248 * - Comments are in C style. C++ style comments are used for temporary
249 * disabling a few lines of code.
250 *
251 * - Sligtly complex boolean expressions are splitt into multiple lines,
252 * putting the operators first on the line and indenting it all according
253 * to the nesting of the expression. The purpose is to make it as easy as
254 * possible to read.
255 * Example:
256 * @code
257 * if ( RT_SUCCESS(rc)
258 * || (fFlags & SOME_FLAG))
259 * @endcode
260 *
261 * - No unnecessary parentheses in expressions (just don't over do this
262 * so that gcc / msc starts bitching). Find a correct C/C++ operator
263 * precedence table if needed.
264 *
265 *
266 * @subsection sec_vbox_guideline_optional_prefix Variable / Member Prefixes
267 *
268 * - The 'g_' (or 'g') prefix means a global variable, either on file or module level.
269 *
270 * - The 's_' (or 's') prefix means a static variable inside a function or class.
271 *
272 * - The 'm_' (or 'm') prefix means a class data member.
273 *
274 * - The 'p' prefix means pointer. For instance 'pVM' is pointer to VM.
275 *
276 * - The 'a' prefix means array. For instance 'aPages' could be read as array
277 * of pages.
278 *
279 * - The 'c' prefix means count. For instance 'cbBlock' could be read, count
280 * of bytes in block.
281 *
282 * - The 'off' prefix means offset.
283 *
284 * - The 'i' or 'idx' prefixes usually means index. Although the 'i' one can
285 * sometimes just mean signed integer.
286 *
287 * - The 'e' (or 'enm') prefix means enum.
288 *
289 * - The 'u' prefix usually means unsigned integer. Exceptions follows.
290 *
291 * - The 'u[1-9]+' prefix means a fixed bit size variable. Frequently used
292 * with the uint[1-9]+_t types and with bitfields.
293 *
294 * - The 'b' prefix means byte or bytes.
295 *
296 * - The 'f' prefix means flags. Flags are unsigned integers of some kind or bools.
297 *
298 * - The 'ch' prefix means a char, the (signed) char type.
299 *
300 * - The 'wc' prefix means a wide/windows char, the RTUTF16 type.
301 *
302 * - The 'uc' prefix means a Unicode Code point, the RTUNICP type.
303 *
304 * - The 'uch' prefix means unsigned char. It's rarely used.
305 *
306 * - The 'sz' prefix means zero terminated character string (array of chars). (UTF-8)
307 *
308 * - The 'wsz' prefix means zero terminated wide/windows character string (array of RTUTF16).
309 *
310 * - The 'usz' prefix means zero terminated Unicode string (array of RTUNICP).
311 *
312 * - The 'pfn' prefix means pointer to function. Common usage is 'pfnCallback'
313 * and such like.
314 *
315 *
316 * @subsection sec_vbox_guideline_optional_misc Misc / Advice / Stuff
317 *
318 * - When writing code think as the reader.
319 *
320 * - When writing code think as the compiler.
321 *
322 * - When reading code think as that it's fully of bugs - find them and fix them.
323 *
324 * - Pointer within range tests like:
325 * @code
326 * if ((uintptr_t)pv >= (uintptr_t)pvBase && (uintptr_t)pv < (uintptr_t)pvBase + cbRange)
327 * @endcode
328 * Can also be written as (assuming cbRange unsigned):
329 * @code
330 * if ((uintptr_t)pv - (uintptr_t)pvBase < cbRange)
331 * @endcode
332 * Which is shorter and potentially faster. (1)
333 *
334 * - Avoid unnecessary casting. All pointers automatically casts down to void *,
335 * at least for non class instance pointers.
336 *
337 * - It's very very bad practise to write a function larger than a
338 * screen full (1024x768) without any comprehendable and explaining comments.
339 *
340 * - More to come....
341 *
342 *
343 * (1) Important, be very careful with the casting. In particular, note that
344 * a compiler might treat pointers as signed (IIRC).
345 *
346 *
347 *
348 *
349 * @section sec_vbox_guideline_warnings Compiler Warnings
350 *
351 * The code should when possible compile on all platforms and compilers without any
352 * warnings. That's a nice idea, however, if it means making the code harder to read,
353 * less portable, unreliable or similar, the warning should not be fixed.
354 *
355 * Some of the warnings can seem kind of innocent at first glance. So, let's take the
356 * most common ones and explain them.
357 *
358 * @subsection sec_vbox_guideline_warnings_signed_unsigned_compare Signed / Unsigned Compare
359 *
360 * GCC says: "warning: comparison between signed and unsigned integer expressions"
361 * MSC says: "warning C4018: '<|<=|==|>=|>' : signed/unsigned mismatch"
362 *
363 * The following example will not output what you expect:
364@code
365#include <stdio.h>
366int main()
367{
368 signed long a = -1;
369 unsigned long b = 2294967295;
370 if (a < b)
371 printf("%ld < %lu: true\n", a, b);
372 else
373 printf("%ld < %lu: false\n", a, b);
374 return 0;
375}
376@endcode
377 * If I understood it correctly, the compiler will convert a to an unsigned long before
378 * doing the compare.
379 *
380 *
381 * @section sec_vbox_guideline_svn Subversion Commit Rules
382 *
383 *
384 * Before checking in:
385 *
386 * - Check Tinderbox and make sure the tree is green across all platforms. If it's
387 * red on a platform, don't check in. If you want, warn in the \#vbox channel and
388 * help make the responsible person fix it.
389 * NEVER CHECK IN TO A BROKEN BUILD.
390 *
391 * - When checking in keep in mind that a commit is atomical and that the Tinderbox and
392 * developers are constantly checking out the tree. Therefore do not split up the
393 * commit unless it's into 100% indepentant parts. If you need to split it up in order
394 * to have sensible commit comments, make the sub-commits as rapid as possible.
395 *
396 * - Make sure you add an entry to the ChangeLog file.
397 *
398 *
399 * After checking in:
400 *
401 * - After checking-in, you watch Tinderbox until your check-ins clear. You do not
402 * go home. You do not sleep. You do not log out or experiment with drugs. You do
403 * not become unavailable. If you break the tree, add a comment saying that you're
404 * fixing it. If you can't fix it and need help, ask in the \#innotek channel or back
405 * out the change.
406 *
407 * (Inspired by mozilla tree rules.)
408 */
409
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette