]> Creatis software - bbtkGEditor.git/blob - doc/UserDoxygen/CodingStyle.html
Bug #1760
[bbtkGEditor.git] / doc / UserDoxygen / CodingStyle.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html><head>
3    <meta http-equiv="Content-Type"
4    content="text/html;charset=iso-8859-1"><title>bbtk Developpers</title></head>
5
6 <body>
7
8 <!--#######################################################################-->
9 <h1>bbtk coding style (and other religious/agnostic beliefs)</h1>
10 <hr size="1"><address style=""></address>
11
12 <pre>* Introduction:
13    The following coding style intends to ease the work of developpers
14    themselves but also of users who will study, maintain, fix, and extend
15    the code. Any bread crumbs that you can drop in the way of explanatory
16    names and comments will go a long way towards helping other readers and
17    developers.
18    Keep in mind that to a large extent the structure of code directly
19    expresses its implementation.
20                                                                                 
21 * Language:
22  - C++ (for the kernel) and Python (for the wrappers).
23  - all the names (variables, members, methods, functions) and comments
24    should be based on English. Documentation, guides, web site and other
25    informations should be in English.
26    Make sure you use correct (basic) English and complete, grammatically
27    correct sentences for comments and documentation.
28                                                                                 
29 * General layout:
30  - Each line of code should take no more than 79 characters. Break the code
31    across multiple lines as necessary.
32  - Methods and functions should keep a reasonable number of lines when
33    possible (a typical editor displays 50 lines). Avoid code duplication.
34    Always prefer creating a new method or function to duplication.
35    A high indentation level generally suggests the need for a new
36    method or function.
37  - All the code should be properly indented. The appropriate indentation
38    level is TWO spaces for each level of indentation. DO NOT USE TABS.
39    Set up your editor to insert spaces. Using tabs may look good in your
40    editor but will wreak havoc in others, or in external tools (e.g. side
41    by side diffs).
42  - The declaration of variables within classes, methods, and functions
43    should be one declaration per line. Provide them with default values
44    and don't rely on compilers for default initialization.
45                                                                                 
46 * Naming conventions:
47  - Generalities:
48    In general, names are constructed by using case change to indicate
49    separate words, as in ImageDataSize (standing for "image data size").
50    Underscores are not used. Variable names are choosen carefully with the
51    intention to convey the meaning behind the code. Names are generally
52    spelled out; use of abbreviations is discouraged.
53    [Note: abbreviation are allowable when in common use, and should be in
54     uppercase as in LUT or RGBA.]
55    While this does result in long names, it self-documents the code.
56  - Naming Files:
57    Files should have the same name as the class, with a "bbtk" prepended.
58    Header files are named .h, while implementation files are named either
59    .cxx or .txx, depending on whether they are implementations of templated
60    classes. For example, the class bbtk::BlackBox is declared and defined
61    in the files bbtkBlackBox.h and bbtkBlackBox.cxx.
62  - Naming Class Data Members, Methods, and Functions:
63    Class data members (aka Attributes) are named beginning with a lower case 'm'
64    (m as 'member'!) followed by capital letter as in mGroupPixel, in order not
65    be confused with methods names.
66    Global functions and class methods, either static or class members, are
67    named beginning with a capital letter, as in GetImageDataSize().
68  - Naming Local Variables:
69    Local variables begin in lowercase. There is more flexibility in the
70    naming of local variables although they still should convey some
71    semantics.
72  - Naming function parameters:
73    Function parameters begin in lowercase. There is more flexibility in the
74    naming of function parameters although they still should convey some
75    semantics.
76                                                                                  
77 * Classes:
78  - Don't use the inline keyword when defining an inline function
79    within a class definition.
80    (Any method defined within a .h file is ipso facto considered as 'inline'.
81    Dont write useless stuff!)
82  - As stated in the "Naming conventions" section, class data members
83    named beginning with a lower case 'm' followed by capital letter 
84    as in mGroupPixel.
85    But the parameter names of method should be named with a lowercase
86    letter (in order to distinguish at a glance data members, from parameters
87    and also to avoid potential collisions with data members):
88       void A::SetGroupPixel( int groupPixel )
89       {
90          mGroupPixel = groupPixel;
91       }
92  - Don't use trailing ';' in inline function definition.
93    use :
94    void A::SetGroupPixel( int groupPixel ){mGroupPixel = groupPixel;}
95      NOT
96    void A::SetGroupPixel( int groupPixel ){mGroupPixel = groupPixel;};
97  - Do not repeat the 'virtual' keyword when overriding virtual base methods
98    in declaration of subclasses:
99      class A
100      {
101         virtual void foo(...);
102      };
103      class B : public bbtk::A
104      {
105         void foo(...);          // and NOT: virtual void foo(...);
106      };
107      
108     (when the keyword 'virtual' is used at the parent level, it's propagated 
109      for all the child classes)
110
111  - In declaration of subclasses, always preprend the class name with 'bbtk::'
112    in order not to confuse Umbrello ( OpenSource UML diagram generator)
113      class A
114      {
115         ...
116      };
117      class B : public bbtk::A // and NOT: class B: public A
118      {
119         ...   
120      };    
121  - The public, protected, private declarations should be at the
122    same indent level as the class. Use :
123      class A
124      {
125      public:
126         void bar(...);
127      protected:
128         void foo(...);  
129      private:
130         void pff(...);
131      };
132      
133  - The Data members should be declared at the end of the class declaration :
134      class A
135      {
136      public:
137         void bar(...);
138      protected:
139         void foo(...);
140      private:
141         void pff(...);
142
143      // --- Data members
144      
145      public:
146         int mPublicCounter;
147      protected:
148         int mProtectedCounter;
149      private:
150         int mPrivateCounter;     
151      }; 
152  
153  - Method and functions devoided of arguments should not use the void
154    notation. Use :
155      SomeType Header::GetPixelData()
156    and not
157      SomeType Header::GetPixelData(void)
158                                                                                 
159 * Use of braces:
160  - Braces must be used to delimit the scope of an if, for, while, switch, or
161    other control structure. Braces are placed on a line by themselves, and
162    at the same indentation level as the control structure to which they
163    belong:
164       for (i=0; * i&lt;3; i++)
165       {
166          ...
167       }
168    and NOT :
169       for (i=0; * i&lt;3; i++) {
170          ...
171       }   
172    or when using an if:
173       if ( condition )
174       {
175          ...
176       }
177       else if ( other condition )
178       {
179          ...
180       }
181       else
182       {
183         ....
184       }
185     and NOT :
186       if ( condition ) {
187          ...
188       } else if ( other condition ) {
189          ...
190       } else {
191          ....
192       }    
193    You can choose to use braces on a line with a code block when
194    the block consists of a single line:
195       if ( condition ) { foo=1; }
196       else if ( condition2 ) { foo=3; }
197       else { return; }
198    or
199       for (i=0; i&lt;3; ++i) {x[i]=0.0;}
200    Methods and functions should follow the same usage of braces:
201       void File::ParsePixelData()
202       {
203          ...
204       }
205
206 * Special layout:
207  - Avoid code mixed with comments on a single line. Instead, prepend the
208    logical blocks of code with the concerned comments.
209  - Use parentheses around conditions e.g. with an if statement:
210       if ( someLocalVariable == 2 ) { ... }
211  - Add spaces around parentheses, or braces. Use
212       if ( someLocalVariable == 2 ) { mClassMember += 1; }
213    and not
214       if (someLocalVariable == 2) {mClassMember += 1;}
215  - Add spaces around each side of the assignement operator, and
216    around binary operators used in boolean expression. Use
217       someLocalVariable = mClassMember * 2;
218       if ( someLocalVariable == 2 || mClassMember == 2 ) ...
219    and not
220       someLocalVariable=mClassMember*2;
221       if ( someLocalVariable==2||mClassMember==2 ) ...
222                                                                                 
223 * Miscelaneous:
224  - Don't use underscores. Don't use tabs. Don't use control characters
225    like ^M. Anyhow, cvs is configured to reject such commits.
226  - Comments should be in C++ style ("// ...", two slashes, per line). Don't
227    use C style comments ("/* ... */").
228  - The last line of a file should terminate with "\n".
229  - Returned arguments of methods and functions should not be wrapped with
230    parentheses. Use
231       return iter-&gt;second;
232    but do not use
233       return ( iter-&gt;second );
234                                                                                 
235 * Debugging and Verbose modes:
236    Never use std::cout. Instead use the bbtkMessage, bbtkDebugMessage, bbtkWarning or bbtkError macros and their variants. Example:
237       #include "bbtkMessageManager.h"
238       ...
239       {
240          bbtkDebugMessageInc("MyClass",9,"Local function name: entering.");
241          ...
242          bbtkDecTab("MyClass",9);
243       }
244     will send the message to std::cout when the Debug messages are compiled 
245     and the Message Level for the category of messages "MyClass" is greater than 9.
246                                                                                 
247 * Documentation:
248    The Doxygen open-source system is used to generate on-line documentation.
249    Doxygen requires the embedding of simple comments in the code which is in
250    turn extracted and formatted into documentation. See :
251       http://www.stack.nl/~dimitri/doxygen/
252    for more information about Doxygen.
253  - Documenting a class:
254    Classes should be documented using the class and brief doxygen commands,
255    followed by the detailed class description:
256       /**
257        * \class Header
258        * \brief Header acts as container of Dicom elements of an image.
259        *
260        * Detailed description of the class is provided here
261        * ...
262        */
263    The key here is that the comment starts with /**, each subsequent line has
264    an aligned *, and the comment block terminates with a */.
265  - Documenting class members and inline methods:
266    All the members and the inline methods should be documented within
267    the class declaration ( .h file) as shown in the following example:
268       class Header
269       {
270          /// True when parsing was successfull. False otherwise.
271          bool mReadable = false;
272                                                                                 
273          /// \brief The number of lines of the image as interpreted from
274          ///        the various elements encountered at header parsing.
275          int mNumberOfLines = -1;
276                                                                                 
277          /// Predicate implemented as accessor around \ref mReadable.
278          bool IsReadable() { return mReadable; }
279       };
280  - Documenting a Method:
281    Methods should be documented using the following comment block style
282    as shown in the following example:
283                                                                                 
284       /**
285        * \brief  Within the Dicom Elements (parsed with the public and private
286        *         dictionaries), look for the element value representation of
287        *         a given tag.
288        * @param  group  Group number of the searched tag.
289        * @param  elem Element number of the searched tag.
290        * @return Corresponding element value representation when it exists,
291        *         and the string "bbtk::Unfound" otherwise.
292        */
293       std::string Document::GetEntryByNumber(guint16 group, guint16 elem)
294       {
295          ...
296       }
297                                                                                 
298 * External includes and C style:
299  - Only the C++ standard library and the STL includes should be used.
300    When including don't use the .h extension (use #include <iostream>
301    instead of #include <iostream.h>).
302    Note: include the stl header AFTER the bbtk ones (otherwise pragma
303          warnings won't work).
304  - Don't use the C standard library. Don't include stdio.h, ctype.h...
305    Don't use printf(), sprinf(), FILE*...
306  - Don't use the NULL notation (neither as macro, nor as const int NULL=0).
307    A pointer that doesn't refer to an object should simply be defined as
308       DataPointer *myDataPointer = 0;
309                                                                                 
310 * Basic types:
311  - Assume T is a given type. When declaring or defining with the
312    "pointer to T" notation, the * character must be adjacent to
313    the variable and not the type. That is use
314       T *foo = 0;
315    and not
316       T* foo = 0;
317    nor
318       T * foo = 0;
319  - Assume T is a given type. When declaring or defining with the
320    "reference to T" notation, the &amp; character must be adjacent to
321    the variable and not the type. That is use :
322       T &amp;foo = 0;
323    and not
324       T&amp; foo = 0;
325
326    (Doxygen will not have any longer to correct)
327
328  - Always define a typedef for a new type and be consistent in usage.
329    Use :
330       typedef Header *HeaderPointer;
331       HeaderPointer myHeaderPointer;
332       
333  - One notorious counter example for non using C style inclusion concerns
334    exact-width integers (since there seem to be no equivalent for C++).
335    When using exact-width integers use the typedef names defined by
336    the Basic ISO C99: 7.18 Integer types i.e.
337       int8_t     int16_t     int32_t     int64_t (signed integers)
338    and
339       uint8_t    uint16_t    uint32_t    uint64_t (unsigned integers).
340    Conversion table is then:
341     unsigned char       -&gt; uint8_t;
342     unsigned short      -&gt; uint16_t;
343     unsigned int        -&gt; uint32_t;
344     unsigned long       -&gt; uint32_t;
345     unsigned long long  -&gt; uint64_t;
346     (signed) char       -&gt; int8_t;
347     short               -&gt; int16_t;
348     int                 -&gt; int32_t;
349     long                -&gt; int32_t;
350     long long           -&gt; int64_t;
351    Hence do not use declarations like "unsigned int".
352    With g++, accessing those typedef is achieved by the following
353       #include &lt; stdint.h &gt;
354 </iostream.h></iostream></pre>
355
356
357 <!--#######################################################################-->
358 <hr size="1"><address style=""></address>
359
360 </body></html>