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