1 | Legacy C/C++-Style guide for Singular {#legacystyleguide} |
---|
2 | ===================================== |
---|
3 | |
---|
4 | Please also note the [newer C/C++ programming style guide](@ref styleguide) |
---|
5 | and the [Singular build system description](@ref bs_page). |
---|
6 | |
---|
7 | [TOC] |
---|
8 | |
---|
9 | |
---|
10 | ## C/C++ files - names (applies to headers as well) |
---|
11 | - each C++ file should have the extension .cc |
---|
12 | - each C file should have the extension .c |
---|
13 | - each header file should have the extension .h |
---|
14 | it should be possible to include it in C and C++ sources |
---|
15 | - converted to lower case, each file name must be unique in the |
---|
16 | first 8 characters |
---|
17 | - it is recommended to use only lower case file names |
---|
18 | |
---|
19 | ## C/C++ files - structure |
---|
20 | - TODO: What about Copyright note? |
---|
21 | (Contained in COPYING unless otherwise specified). |
---|
22 | - each C/C++ file (abc.c/abc.cc/abc.h) should start with a short comment |
---|
23 | about its purpose in doxygen format (TODO: see file templates) giving |
---|
24 | at least the filename and a brief description of the contents. |
---|
25 | (Each header of a file should contain an Id/Rev field) |
---|
26 | - order "#include" statements from global to local scope: |
---|
27 | i. first: all system include files: |
---|
28 | #include <iostream>, #include <boost/shred_ptr.h> |
---|
29 | (remember to include optional include files in #ifdef ... #end) |
---|
30 | ii. only source files: #include "mod2.h" |
---|
31 | iii. at last: all other files (which you really need): |
---|
32 | #include "poly.h" etc. |
---|
33 | - paths in "#include" statements should be avoided (should be specified by |
---|
34 | build system level instead) |
---|
35 | |
---|
36 | ## Header files |
---|
37 | - see C/C++ files - structure! |
---|
38 | - each header file abc.h should contain a multiple inclusions preventing |
---|
39 | mechanism as follows: |
---|
40 | |
---|
41 | #ifndef ABC_H |
---|
42 | #define ABC_H |
---|
43 | |
---|
44 | // .... declarations ... |
---|
45 | |
---|
46 | #endif // ABC_H |
---|
47 | |
---|
48 | - do NOT include mod2.h! |
---|
49 | - include only the header files you really need |
---|
50 | (use forward declarations wherever possible) |
---|
51 | - all declarations (macros, types, variables, enumerations, function |
---|
52 | parameters...) should be documented in doxygen format. Brief comments are |
---|
53 | mandatory, long comments are optional (TODO: see file templates) |
---|
54 | - class-/function-/member variable-/... comments should be written in the |
---|
55 | doxygen format (see Doxygen quick reference card) |
---|
56 | - further (non doxygen) comments can be used to separate the file into easily |
---|
57 | visible sections |
---|
58 | |
---|
59 | ## format |
---|
60 | - general screen width: 80 columns |
---|
61 | - each procedure declarations should be in one line, if possible |
---|
62 | - the number of required function parameters should be as small as possible |
---|
63 | - curly braces: Matching curly brackets should be either vertically |
---|
64 | or horizontally aligned. |
---|
65 | - the "else" keyword indents the same as its matching "if" |
---|
66 | - indentation should be small |
---|
67 | (e.g. two positions (spaces) for each level of nesting) |
---|
68 | - avoid tabs: their interpretation differs from editor to editor. |
---|
69 | - use empty lines seldom: only to break up very long routines and between |
---|
70 | routines |
---|
71 | - avoid code copying/duplication |
---|
72 | - declare local variables as late as possible and with the smallest possible |
---|
73 | visibility scope |
---|
74 | - avoid using "goto", "continue", "break" statements |
---|
75 | (save for "switch/case" blocks and error handling) |
---|
76 | - compiler warnings should be enabled and regarded as errors |
---|
77 | - whenever possible, constants should be defined as "const variables" |
---|
78 | not via "#define". |
---|
79 | Non pure C++ parts must use #define. |
---|
80 | - Consider the choice between macros and inline function very careful, |
---|
81 | prefer inline functions: |
---|
82 | - macros are not type safe |
---|
83 | + macros are allways inlined |
---|
84 | - arguments to macros can be multiply computed |
---|
85 | |
---|
86 | - "inline" is only a hint for the optimizer (especially in the C parts): |
---|
87 | in non-optimzed code these functions are NOT inlined. |
---|
88 | -/+ inline functions are not generic (requires the defined types) |
---|
89 | |
---|
90 | ## Naming conventions: |
---|
91 | - All code and global variables must conform to this naming convention, |
---|
92 | it does not apply to local variables. |
---|
93 | - the names consists of a short (small letter) prefix, |
---|
94 | the first letter of each following word is capitalized |
---|
95 | (The routines Werror/WerrorS/Warn/WarnS/Print/PrintS have an empty prefix) |
---|
96 | - the prefix describes the area the name belongs to: |
---|
97 | p: polynomial operations |
---|
98 | n/np/nl/na/: number operations (general/Zp/Q/alg.ext.) |
---|
99 | k: std engine |
---|
100 | ... |
---|
101 | - _ (underscore) is only used as a last part of the prefix: |
---|
102 | (example: p_Add): the last argument is the base ring |
---|
103 | - macros are in capital letters (except used as a procedure) |
---|
104 | |
---|
105 | |
---|
106 | |
---|
107 | ## Comments |
---|
108 | - class-/function-/member variable-/... comments should be written in the |
---|
109 | doxygen format (see Doxygen quick reference card) |
---|
110 | - documentation should explain the purpose of each type/function/parameter/., |
---|
111 | as well as its return value or any preconditions/side effects if applicable |
---|
112 | - comments in source files about implementation details need not be in |
---|
113 | doxygen format |
---|
114 | - do not comment on trivial matters. Implementation details should be |
---|
115 | sufficiently commented for others to understand the inner workings of the |
---|
116 | code. |
---|
117 | - document difficult algorithms by a reference to an article/book/etc. |
---|
118 | |
---|
119 | ## Checks / Debugging aids |
---|
120 | - interpreter routines have to check their input |
---|
121 | - use const wherever possible/suitable (especially in declarations of input |
---|
122 | parameters to functions/methods provided as pointers or references or for |
---|
123 | methods that do not change the state of an object, consider delaring |
---|
124 | variables "mutable" whenever suitable) |
---|
125 | |
---|
126 | - kernel routines have to document their requirements, |
---|
127 | the checks have to be done in the interpreter. |
---|
128 | Repeat the checks only within #ifndef SING_NDEBUG/#endif |
---|
129 | or via assert. |
---|
130 | - input should be checked to conform with the documentation via assume |
---|
131 | (if this is simple) |
---|
132 | - more time consuming tests should be within |
---|
133 | #ifdef PDEBUG/#ifdef KDEBUG/#ifdef LDEBUG |
---|
134 | (see mod2.h) |
---|
135 | - case statements (or equivalent if/else constructs) |
---|
136 | should always have an default entry |
---|
137 | (maybe an error message) |
---|
138 | |
---|
139 | ## C++ features |
---|
140 | - to avoid confusion: "struct" should be a C object, |
---|
141 | if you really need C++ extensions, use "class". |
---|
142 | - "and"/"or"/"not" are not recognized by all compilers, use &&, &, ||, |, ! |
---|