VirtualBox

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

Last change on this file since 19286 was 19010, checked in by vboxsync, 15 years ago

doc,Makefile.kmk: Draft for the makefile guidelines. (would've been of more use a year back, but better late than never?)

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