source: git/doc/C_CPP_StyleGuide.md @ 662704

spielwiese
Last change on this file since 662704 was 75f460, checked in by Hans Schoenemann <hannes@…>, 9 years ago
format
  • Property mode set to 100644
File size: 13.6 KB
Line 
1Style Guide for the Further Development of SINGULAR in C / C++ {#styleguide}
2==============================================================
3
4[TOC]
5
6## Preface
7
8The purpose of this document is to provide a common style guide for the further code development for SINGULAR in C and C++. Observation of this style guide will
9
10 * increase the homogeneity of newly developed code both in format and semantics,
11 * ease understanding of code in the team of SINGULAR developers,
12 * ease maintenance of the code, and
13 * increase its reusability.
14
15The given style guide is _not_ fixed, in the sense that it may be
16updated and modified at any time, in order to further increase its utility.
17**On the other hand, developers are expected to stick to the
18respective latest version of this style guide.**
19In case of minor changes to this style guide, old code sources need _not_ be adjusted to obey the newest version of the style guide. However, in case of major changes such adjustments may become advisable.
20
21There may be collisions with other existing and widely-used style guides, e.g. when including `std` sources. Such code _may be used as it is_, i.e., it does _not_ need to be wrapped in code which conforms to the style guide at hand.
22
23See also the [Build System description](@ref bs_page) and the
24[Legacy C/C++ programming style guide](@ref legacystyleguide).
25
26## Naming Conventions
27
28For the rest of this document, we use the term _method_ for any algorithm which is declared as part of a class definition, including static algorithms. For all other algorithmic code we use the term _procedure_. By the term _routines_, we refer to all methods and procedures.
29
30This paragraph defines all conventions relating to names of files, classes, methods, procedures, and variables.
31
32### General Remarks
33
34 * **As a general rule we state that all names should be meaningful and relate to the objects they name.**
35 * All names are in British English.
36 * Names exclusively consist of lower and upper case letters of the english alphabet, digits, and the underscore character, `_`. (Note that this excludes all other characters, such as German umlauts.)
37 * Each name complies to one of the below specified patterns. Besides these, there are _no additional valid names_. All patterns are explained by examples and an informal description. For a formal definition in the _Backus Naur Formalism_ (BNF) we point the reader to the Appendix below.
38
39### Naming Conventions for Files
40
41 * Examples: `bucketPoly.h, myStructure_T.c`
42 * Informal description:
43    * File names are in _lowerCamelCase_, followed by the dot `.` and a file extension.
44    * One exception to this rule are files containing template definitions. There names end with two underscores and the capital letter `T` (followed by the dot and the file extension).
45    * Header files have the extension `h`. (I.e., `hpp` is not allowed.)
46    * C / C++ sources end with `c` and `cc`, respectively.
47 * Other file extensions, besides `h`, `c`, and `cc` may be sensible, e.g. `l` (_el_) for grammar files, etc.
48 * Special first _words_ in a file name may be used to indicate their primary purpose, e.g. `test...`. Note that thereby, such files will nicely group in alphabetically ordered file explorers.
49 * If possible, files should be named after an important class or routine implemented in that file.
50 * All files in the entire source code tree _must_ have mutually distinct names, in order to avoid ambiguities, e.g. when including numerous header files. Distinctness must hold _modulo capitalization_, that is, the file names `BucketPoly.h` and `bucketPoly.h` will _not_ be regarded distinct.<br />
51   Note that this rule may be hard to ensure over time, as different developers may create different files with the same name(!) in different sub-folders. Thus, the rule needs to be re-established whenever a violation becomes obvious.
52
53### Naming Conventions for Classes and Types
54
55 * Example: `BucketPoly`
56 * Informal description:
57    * Class and type names are in UpperCamelCase.
58
59### Naming Conventions for Routines
60
61(See the above remark on the distinction between the terms _method_, _procedure_, and _routine_.)
62
63 * Examples: `gcdAlgorithmV2, isPrime, areCoprime, getValue`
64 * Informal description:
65    * Routines names are in lowerCamelCase, i.e., constructed as class names, except the first letter is lower-case.
66 * Private class attributes implement so-called _getter and setter methods_. Their names start with `get` and `set`, respectively.
67 * For performance reasons, short routines should be declared `static inline`, although the inlining of code cannot be enforced since `inline` declarations are just recommendations to the compiler but _may be ignored_. Getter and setter methods are canonical candidates for inlining.
68 * Routines with return type `bool` start with `is` or `are`.
69
70### Naming Conventions for Variables
71
72 * Examples: `SING_NDEBUG, nPolyCounter, i, m_pValueList`
73 * Informal description:
74    * Global preprocessor constants, such as `SING_NDEBUG`, consist of capitalized words separated by the underscore character `_`. Capitalization is only allowed for preprocessor constants, i.e., all other variables _must not _be capitalized.
75    * Variables which are locally used in routines are in lowerCamelCase. If they are used in just one block, e.g. in a `for` loop, the _may_ consist of just one lower-case letter. In longer variable names, the first letter _may_ be used to indicate the type of the variable. Recommendations for such indications _may_ be these (Note that this is _not_ compulsory):
76       * `p` for a pointer, as e.g. in `pSyzList`, but also `p` for `poly` is sensible.
77       * `b` for a `bool`, as e.g. in `bConditionXHolds`,
78       * `n` for anything that can be counted, i.e. `int`, or `long`,
79       * `s` for a `string`,
80       * `c` for a `char`,
81       * `d` for a `double`,
82       * `f` for a `float`,
83       * `it` for an `Iterator`,
84       * `a` for an `array`.
85    * Private member variables in a class declaration start with `m_`, followed by lowerCamelCase; see the above example. Again, the first letter of the lowerCamelCase part may be used to indicate the type of the variable.
86 * **Note that we do not allow for public class variables.** Public access must be implemented via publicly declared class methods which retrieve or set private class member variables. Often, this will be realized just by declaring getters and setters as public methods (as opposed to their normal private declaration).
87 * Preprocessor constants _must not_ be used for representing variables with a mathematical or algorithm-related meaning. The proper way for representing these variables is a `const` variable declaration which will also allow for type checking at compile time.
88
89## Structuring the Code
90
91### General
92
93 * The use of `using namespace foo::bar;` in header files is forbidden; due to possible ambiguities when including numerous header files.
94 * Class variables of basic C type need to be initialized using a default value.
95 * If a programmer does not want an instance of a class to be copied, then the **copy** and **assignment** constructors need to be declared `private`.
96 * **copy, assignment** and **default** constructors of any class are _either all implemented or all not implemented_.
97 * Routines that are intended to leave the object `* this` unaltered need to be declared as `const`.
98 * Likewise, routine parameters that are intended to be left unaltered by that routine need to be declared as `const`.
99 * The usage of `goto`, `continue` and `break` is forbidden; with the following exceptions:
100    * `break` may be used in `case`, `for`, `loop` and `while` blocks to allow for an immediate termination of that block.
101    * `goto` may be used in very rare cases by experts only, for reasons of clarity of the code.
102
103### Includes in Header Files (*.h)
104
105 * Any header file, e.g., `BucketPoly.h` _must_ start with a guard, that is, the following lines of code
106
107~~~~~~~~~~~~~~~{.c}
108    #ifndef BUCKET_POLY_H
109    #define BUCKET_POLY_H
110~~~~~~~~~~~~~~~
111
112   and must end with the line
113
114~~~~~~~~~~~~~~~{.c}
115    #endif
116~~~~~~~~~~~~~~~
117
118 * The guard _should be_ the capitalized filename with the dot `.` replaced by an underscore `_` and suitably inserted additional underscores (corresponding to the camelCase structure of the filename, see example).
119 * Only those header files are to be included that are actually needed inside the including piece of code.
120 * Do not include `mod2.h` in header files.
121 * The proper ordering of `include` statements in header files is:
122    1. System related includes,
123    2. additional third-party sources,
124    3. SINGULAR related includes (in order to overwrite defect symbols)
125 * To ease readability, any `#endif` is followed by a _new line_ containing a comment in `/*, */` which repeats the corresponding `#ifndef` information (but without the keyword `ifdef` or `ifndef`), e.g.
126
127~~~~~~~~~~~~~~~{.c}
128    #endif
129    /* BUCKET_POLY_H */
130~~~~~~~~~~~~~~~
131
132   (Here we demand a _new line_ in order to avoid compiler warnings concerning characters following the `#endif` statement in the same line of code.)
133
134### Includes in Source Files (*.c, *.cc)
135
136The proper ordering of `include` statements in source files is:
137 1. System related includes,
138 2. `include mod2.h`,
139 3. System related includes, which are optional (depending on `mod2.h`)
140 4. all remaining and actually needed `include` statements.
141
142### On the Use of Macros
143
144 * The use of macros should be limited to rare cases, when other constructs will not work or would result in unclear code.
145 * Macros may be used for compiler switches.
146 * Moreover, whenever `inline` mechanisms are not applicable, e.g., when using the system variables `_FILE_` and `_LINE_,` macros may as well be used.
147
148### Simple Checks and Further Debugging Utilities
149
150 * All routines are expected to check their input parameters against their specification (see paragraph on _In-Code Documentation_), and – as far as possible – for sensibility regarding their possible combination in the debug version (i.e. if `SING_NDEBUG` is NOT defined).
151 * Likewise, if easy to implement, all relations among output parameters that are to be ensured by a method, need to be checked at the end of the method.
152 * The afore mentioned checks for input and output parameters of a method will only be checked in debug mode. Thus they do not influence runtime performance of any non-debug version of SINGULAR.
153 * Each `case` block implements a `default` mode of operation. In case this default must never be reached, the `default` implements an error message or some similar behavior which supports debugging.
154
155### Formatting
156
157 * Any line of code is at most 80 characters long.
158 * In case of a non-fitting routine declaration, the declaration may be linefeeded between routine parameters. Then, the next line has to be indented such that method parameters are left-aligned, as in the following example:
159
160~~~~~~~~~~~~~~~
161C& C::multiplyWith10Cs(C& c1, C& c2, ...
162                       C& c9, C& c10)
163~~~~~~~~~~~~~~~
164
165 * Parenthesizes `{` and `}` of blocks which do not fit in a single line are arranged such that they stand in the same text column, i.e., the closing `}` stand exactly below their corresponding opening `{`.
166 * Each sub-block is indented by exactly 2 white-spaces with respect to its immediate parent block. The only exception to that rule are `namespaces`: the first level of indentation of code inside `namespaces` is omitted.
167 * Corresponding `if` and `else` start in the same text column.
168 * The usage of **Tabs** is forbidden, because different editors may provide different interpretations of them. Instead, **whitespaces** are consequently used.
169
170### In-Code Documentation
171
172 * In general, all documentation in the code is going to be processed by Doxygen. Therefore, documentation has to follow Doxygen syntax.<br />
173   In order to ease documentation, template files for `*.h` and `*.cc` files, which conform to both this style guide and Doxygen syntax are provided.
174   See [C source template](@ref templates/template.c), [header template](@ref templates/template.h) and [C++ source template](@ref templates/template.cc).
175 * Each source code file starts with some version information, author, and a short comment about its purpose.
176 * Each routine is preceded by a Doxygen-conformal comment about its input parameters, output values, relations that are expected to hold among them, and possible side effects on other variables, if any.
177 * Difficult and more involved algorithmic parts of routines are documented directly  before or between the corresponding lines of code, even though these comments may not appear in the Doxygen-generated developer's manual.
178 * Even harder algorithmic parts must come with a link to related literature which clarifies the respective passages of the algorithm.
179
180Some doxygen-related links:
181 * Manual <http://www.stack.nl/~dimitri/doxygen/manual/>
182 * QRC: <http://www.digilife.be/quickreferences/QRC/Doxygen%20Quick%20Reference.pdf>, <http://www.sztaki.hu/~szcsaba/software/DoxygenQuickReference.pdf>
183
184## BNF Specification for Naming Conventions
185
186~~~~~~~~~~~~~~~
187Letter ::= A | B | ... | Z
188letter ::= a | b | ... | z
189letters ::= λ | letter letters
190Underscore ::= _
191Digit ::= 0 | 1 | ... | 9
192Digits ::= λ | Digit Digits
193Word ::= Letter letters Digits
194word ::= letter letters Digits
195CapitalizedWord ::= Letter | Letter CapitalizedWord
196UpperCamelCase ::= Word | Word UpperCamelCase
197lowerCamelCase ::= word | word UpperCamelCase
198Dot ::= .
199Suffix ::= h | c | cc | {...further}
200Filename ::= lowerCamelCase Dot Suffix
201ClassOrTypeName ::= UpperCamelCase
202Methodname ::= lowerCamelCase
203LocalBlockVariable ::= letter
204PreprocessorConstant ::= CapitalizedWord | CapitalizedWord _ PreprocessorConstant
205LocalVariable ::= lowerCamelCase
206MemberVariable ::= m Underscore lowerCamelCase
207~~~~~~~~~~~~~~~
208
Note: See TracBrowser for help on using the repository browser.