2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
8 # This software is governed by the CeCILL-B license under French law and
9 # abiding by the rules of distribution of free software. You can use,
10 # modify and/ or redistribute the software under the terms of the CeCILL-B
11 # license as circulated by CEA, CNRS and INRIA at the following URL
12 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
13 # or in the file LICENSE.txt.
15 # As a counterpart to the access to the source code and rights to copy,
16 # modify and redistribute granted by the license, users are provided only
17 # with a limited warranty and the software's author, the holder of the
18 # economic rights, and the successive licensors have only limited
21 # The fact that you are presently reading this means that you have had
22 # knowledge of the CeCILL-B license and that you accept its terms.
23 # ------------------------------------------------------------------------
26 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
28 <meta http-equiv="Content-Type"
29 content="text/html;charset=iso-8859-1"><title>bbtk Developpers</title></head>
33 <!--#######################################################################-->
34 <h1>bbtk coding style (and other religious/agnostic beliefs)</h1>
35 <hr size="1"><address style=""></address>
38 The following coding style intends to ease the work of developpers
39 themselves but also of users who will study, maintain, fix, and extend
40 the code. Any bread crumbs that you can drop in the way of explanatory
41 names and comments will go a long way towards helping other readers and
43 Keep in mind that to a large extent the structure of code directly
44 expresses its implementation.
47 - C++ (for the kernel) and Python (for the wrappers).
48 - all the names (variables, members, methods, functions) and comments
49 should be based on English. Documentation, guides, web site and other
50 informations should be in English.
51 Make sure you use correct (basic) English and complete, grammatically
52 correct sentences for comments and documentation.
55 - Each line of code should take no more than 79 characters. Break the code
56 across multiple lines as necessary.
57 - Methods and functions should keep a reasonable number of lines when
58 possible (a typical editor displays 50 lines). Avoid code duplication.
59 Always prefer creating a new method or function to duplication.
60 A high indentation level generally suggests the need for a new
62 - All the code should be properly indented. The appropriate indentation
63 level is TWO spaces for each level of indentation. DO NOT USE TABS.
64 Set up your editor to insert spaces. Using tabs may look good in your
65 editor but will wreak havoc in others, or in external tools (e.g. side
67 - The declaration of variables within classes, methods, and functions
68 should be one declaration per line. Provide them with default values
69 and don't rely on compilers for default initialization.
73 In general, names are constructed by using case change to indicate
74 separate words, as in ImageDataSize (standing for "image data size").
75 Underscores are not used. Variable names are choosen carefully with the
76 intention to convey the meaning behind the code. Names are generally
77 spelled out; use of abbreviations is discouraged.
78 [Note: abbreviation are allowable when in common use, and should be in
79 uppercase as in LUT or RGBA.]
80 While this does result in long names, it self-documents the code.
82 Files should have the same name as the class, with a "bbtk" prepended.
83 Header files are named .h, while implementation files are named either
84 .cxx or .txx, depending on whether they are implementations of templated
85 classes. For example, the class bbtk::BlackBox is declared and defined
86 in the files bbtkBlackBox.h and bbtkBlackBox.cxx.
87 - Naming Class Data Members, Methods, and Functions:
88 Class data members (aka Attributes) are named beginning with a lower case 'm'
89 (m as 'member'!) followed by capital letter as in mGroupPixel, in order not
90 be confused with methods names.
91 Global functions and class methods, either static or class members, are
92 named beginning with a capital letter, as in GetImageDataSize().
93 - Naming Local Variables:
94 Local variables begin in lowercase. There is more flexibility in the
95 naming of local variables although they still should convey some
97 - Naming function parameters:
98 Function parameters begin in lowercase. There is more flexibility in the
99 naming of function parameters although they still should convey some
103 - Don't use the inline keyword when defining an inline function
104 within a class definition.
105 (Any method defined within a .h file is ipso facto considered as 'inline'.
106 Dont write useless stuff!)
107 - As stated in the "Naming conventions" section, class data members
108 named beginning with a lower case 'm' followed by capital letter
110 But the parameter names of method should be named with a lowercase
111 letter (in order to distinguish at a glance data members, from parameters
112 and also to avoid potential collisions with data members):
113 void A::SetGroupPixel( int groupPixel )
115 mGroupPixel = groupPixel;
117 - Don't use trailing ';' in inline function definition.
119 void A::SetGroupPixel( int groupPixel ){mGroupPixel = groupPixel;}
121 void A::SetGroupPixel( int groupPixel ){mGroupPixel = groupPixel;};
122 - Do not repeat the 'virtual' keyword when overriding virtual base methods
123 in declaration of subclasses:
126 virtual void foo(...);
128 class B : public bbtk::A
130 void foo(...); // and NOT: virtual void foo(...);
133 (when the keyword 'virtual' is used at the parent level, it's propagated
134 for all the child classes)
136 - In declaration of subclasses, always preprend the class name with 'bbtk::'
137 in order not to confuse Umbrello ( OpenSource UML diagram generator)
142 class B : public bbtk::A // and NOT: class B: public A
146 - The public, protected, private declarations should be at the
147 same indent level as the class. Use :
158 - The Data members should be declared at the end of the class declaration :
173 int mProtectedCounter;
178 - Method and functions devoided of arguments should not use the void
180 SomeType Header::GetPixelData()
182 SomeType Header::GetPixelData(void)
185 - Braces must be used to delimit the scope of an if, for, while, switch, or
186 other control structure. Braces are placed on a line by themselves, and
187 at the same indentation level as the control structure to which they
189 for (i=0; * i<3; i++)
194 for (i=0; * i<3; i++) {
202 else if ( other condition )
213 } else if ( other condition ) {
218 You can choose to use braces on a line with a code block when
219 the block consists of a single line:
220 if ( condition ) { foo=1; }
221 else if ( condition2 ) { foo=3; }
224 for (i=0; i<3; ++i) {x[i]=0.0;}
225 Methods and functions should follow the same usage of braces:
226 void File::ParsePixelData()
232 - Avoid code mixed with comments on a single line. Instead, prepend the
233 logical blocks of code with the concerned comments.
234 - Use parentheses around conditions e.g. with an if statement:
235 if ( someLocalVariable == 2 ) { ... }
236 - Add spaces around parentheses, or braces. Use
237 if ( someLocalVariable == 2 ) { mClassMember += 1; }
239 if (someLocalVariable == 2) {mClassMember += 1;}
240 - Add spaces around each side of the assignement operator, and
241 around binary operators used in boolean expression. Use
242 someLocalVariable = mClassMember * 2;
243 if ( someLocalVariable == 2 || mClassMember == 2 ) ...
245 someLocalVariable=mClassMember*2;
246 if ( someLocalVariable==2||mClassMember==2 ) ...
249 - Don't use underscores. Don't use tabs. Don't use control characters
250 like ^M. Anyhow, cvs is configured to reject such commits.
251 - Comments should be in C++ style ("// ...", two slashes, per line). Don't
252 use C style comments ("/* ... */").
253 - The last line of a file should terminate with "\n".
254 - Returned arguments of methods and functions should not be wrapped with
256 return iter->second;
258 return ( iter->second );
260 * Debugging and Verbose modes:
261 Never use std::cout. Instead use the bbtkMessage, bbtkDebugMessage, bbtkWarning or bbtkError macros and their variants. Example:
262 #include "bbtkMessageManager.h"
265 bbtkDebugMessageInc("MyClass",9,"Local function name: entering.");
267 bbtkDecTab("MyClass",9);
269 will send the message to std::cout when the Debug messages are compiled
270 and the Message Level for the category of messages "MyClass" is greater than 9.
273 The Doxygen open-source system is used to generate on-line documentation.
274 Doxygen requires the embedding of simple comments in the code which is in
275 turn extracted and formatted into documentation. See :
276 http://www.stack.nl/~dimitri/doxygen/
277 for more information about Doxygen.
278 - Documenting a class:
279 Classes should be documented using the class and brief doxygen commands,
280 followed by the detailed class description:
283 * \brief Header acts as container of Dicom elements of an image.
285 * Detailed description of the class is provided here
288 The key here is that the comment starts with /**, each subsequent line has
289 an aligned *, and the comment block terminates with a */.
290 - Documenting class members and inline methods:
291 All the members and the inline methods should be documented within
292 the class declaration ( .h file) as shown in the following example:
295 /// True when parsing was successfull. False otherwise.
296 bool mReadable = false;
298 /// \brief The number of lines of the image as interpreted from
299 /// the various elements encountered at header parsing.
300 int mNumberOfLines = -1;
302 /// Predicate implemented as accessor around \ref mReadable.
303 bool IsReadable() { return mReadable; }
305 - Documenting a Method:
306 Methods should be documented using the following comment block style
307 as shown in the following example:
310 * \brief Within the Dicom Elements (parsed with the public and private
311 * dictionaries), look for the element value representation of
313 * @param group Group number of the searched tag.
314 * @param elem Element number of the searched tag.
315 * @return Corresponding element value representation when it exists,
316 * and the string "bbtk::Unfound" otherwise.
318 std::string Document::GetEntryByNumber(guint16 group, guint16 elem)
323 * External includes and C style:
324 - Only the C++ standard library and the STL includes should be used.
325 When including don't use the .h extension (use #include <iostream>
326 instead of #include <iostream.h>).
327 Note: include the stl header AFTER the bbtk ones (otherwise pragma
328 warnings won't work).
329 - Don't use the C standard library. Don't include stdio.h, ctype.h...
330 Don't use printf(), sprinf(), FILE*...
331 - Don't use the NULL notation (neither as macro, nor as const int NULL=0).
332 A pointer that doesn't refer to an object should simply be defined as
333 DataPointer *myDataPointer = 0;
336 - Assume T is a given type. When declaring or defining with the
337 "pointer to T" notation, the * character must be adjacent to
338 the variable and not the type. That is use
344 - Assume T is a given type. When declaring or defining with the
345 "reference to T" notation, the & character must be adjacent to
346 the variable and not the type. That is use :
351 (Doxygen will not have any longer to correct)
353 - Always define a typedef for a new type and be consistent in usage.
355 typedef Header *HeaderPointer;
356 HeaderPointer myHeaderPointer;
358 - One notorious counter example for non using C style inclusion concerns
359 exact-width integers (since there seem to be no equivalent for C++).
360 When using exact-width integers use the typedef names defined by
361 the Basic ISO C99: 7.18 Integer types i.e.
362 int8_t int16_t int32_t int64_t (signed integers)
364 uint8_t uint16_t uint32_t uint64_t (unsigned integers).
365 Conversion table is then:
366 unsigned char -> uint8_t;
367 unsigned short -> uint16_t;
368 unsigned int -> uint32_t;
369 unsigned long -> uint32_t;
370 unsigned long long -> uint64_t;
371 (signed) char -> int8_t;
375 long long -> int64_t;
376 Hence do not use declarations like "unsigned int".
377 With g++, accessing those typedef is achieved by the following
378 #include < stdint.h >
379 </iostream.h></iostream></pre>
382 <!--#######################################################################-->
383 <hr size="1"><address style=""></address>