]> git.lyx.org Git - features.git/blob - development/Code_rules/Rules
Whitespace, only whitespace. Part II.
[features.git] / development / Code_rules / Rules
1 Rules for the code in LyX
2 -------------------------
3 [updated from the C++STYLE distributed with the GNU C++ Standard]
4
5 The aim of this file is to serve as a guide for the developers, to aid us to
6 get clean and uniform code. This document is still incomplete.
7
8 We really like to have new developers joining the LyX Project. However,
9 we have had problems in the past with developers leaving the
10 project and their contributed code in a far from perfect state. Most
11 of this happened before we really became aware of these issues,
12 but still, we don't want it to happen again. So we have put together
13 some guidelines and rules for the developers.
14
15 General
16 -------
17
18 These guidelines should save us a lot of work while cleaning up the code and
19 help us to have quality code. LyX has been haunted by problems coming from
20 unfinished projects by people who have left the team. Those problems will
21 hopefully disappear if the code is easy to hand over to somebody else.
22
23 In general, if you want to contribute to the main source, we expect at least
24 that you:
25
26 - the most important rule first: kiss (keep it simple stupid), always
27   use a simple implementation in favor of a more complicated one.
28   This eases maintenance a lot.
29 - write good C++ code: Readable, well commented and taking advantage of the
30   OO model. Follow the formatting guidelines. See Formatting.
31 - adapt the code to the structures already existing in LyX, or in the case
32   that you have better ideas, discuss them on the developer's list before
33   writing the code.
34 - take advantage of the C++ standard library. especially don't use
35   custom containers when a standard container is usable; learn to use
36   the algorithms and functors in the standard library.
37 - be aware of exceptions and write exception safe code. See Exceptions.
38 - document all variables, methods, functions, classes etc. We are
39   using the source documentation program doxygen, a program that handles
40   javadoc syntax, to document sources. You can download doxygen from :
41
42   http://www.stack.nl/~dimitri/doxygen/
43
44 - we have certain code constructs that we try to follow. See Code
45   Constructs.
46
47
48 Submitting Code
49 ---------------
50
51 It is implicitly understood that all patches contributed to The LyX
52 Project is under the Gnu General Public License, version 2 or later.
53 If you have a problem with that, don't contribute code.
54
55 Also please don't just pop up out of the blue with a huge patch (or
56 small) that changes something substantial in LyX. Always discuss your
57 ideas with the developers on the developer's mailing list.
58
59 When you create the patch, please use "diff -up" since we find that a
60 lot easier to read than the other diff formats. Also please do not
61 send patches that implements or fixes several different things; several
62 patches is a much better option.
63
64 We also require you to provide a ChangeLog entry with every patch, this
65 describes shortly what the patch is doing. The ChangeLog entry follows
66 this syntax:
67
68 1999-12-13  Lars Gullik Bjønnes  <larsbj@lyx.org>
69
70         * src/support/lyxstring.C (find): assert bug fixed.
71
72 Note that there are specific ChangeLogs for most directories; use those
73 rather than the top-level one.
74
75 Code Constructs
76 ---------------
77
78 We have several guidelines on code constructs, some of these exist to
79 make the code faster, others to make the code clearer. Yet others
80 exist to allow us to take advantage of the strong type checking
81 in C++.
82
83 - Declaration of variables should wait as long as possible. The rule
84   is: "Don't declare it until you need it." In C++ there are a lot of
85   user defined types, and these can very often be expensive to
86   initialize. This rule connects to the next rule too.
87
88 - declare the variable as const if you don't need to change it. This
89   applies to POD types like int as well as classes.
90
91 - Make the scope of a variable as small as possible.
92
93 - Make good use of namespaces. Prefer anonymous namespaces to declaring
94   "static" for file scope.
95
96 - Prefer preincrement to postincrement whenever possible.
97   Preincrement has potential of being faster than postincrement. Just
98   think about the obvious implementations of pre/post-increment. This
99   rule applies to decrement too.
100
101         ++T;
102         --U;
103         -NOT-
104         T++; // wrong
105         U--; // wrong
106
107 - Try to minimize evaluation of the same code over and over. This is
108   aimed especially at loops.
109
110         Container::iterator end = large.end();
111         for (Container::iterator it = large.begin(); it != end; ++it) {
112                 ...;
113         }
114         -NOT-
115         for (Container::iterator it = large.begin();
116              it != large.end(); ++it) {
117                 ...;
118         }
119
120 - For functions and methods that return a non-POD type T, return T
121   const instead. This gives better type checking, and will give a
122   compiler warning when temporaries are used wrongly.
123
124         T const add(...);
125         -NOT-
126         T add(...);
127
128 - Avoid using the default cases in switch statements unless you have
129   too. Use the correct type for the switch expression and let the
130   compiler ensure that all cases are exhausted.
131
132         enum Foo {
133                 foo,
134                 bar
135         };
136         Foo f = ...;
137         switch (f) {
138         case foo: ...; break;
139         case bar: ...; break;
140         default: ...; break; // not needed and would shadow a wrong use of Foo
141         }
142
143 Exceptions
144 ----------
145
146 Even if LyX currently is not using exceptions we need to be aware of
147 them. One important thing to realize is that you often do not have to
148 use throw, try or catch to be exception safe. Let's look at the
149 different types of exceptions safety: (These are taken from Herb
150 Sutter's book[ExC++]
151
152 "
153 1. Basic guarantee: Even in the presence of exceptions thrown by T or
154         other exceptions, Stack objects don't leak resources.
155         Note that this also implies that the container will be
156         destructible and usable even if an exception is thrown while
157         performing some container operation. However, if an exception
158         is thrown, the container will be in a consistent, but not
159         necessarily predictable, state. Containers that support the
160         basic guarantee can work safely in some settings.
161
162 2. Strong guarantee: If an operation terminates because of an
163         exception, program state will remain unchanged.
164         This always implies commit-or-rollback semantics, including
165         that no references or iterators into the container be
166         invalidated if an operation fails. For example, if a Stack
167         client calls Top and then attempts a Push that fails because
168         of an exception, then the state of the Stack object must be
169         unchanged and the reference returned from the prior call to
170         Top must still be valid. For more information on these
171         guarantees, see Dave Abrahams's documentation of the SGI
172         exception-safe standard library adaption at:
173
174         http://www.stlport.org/doc/exception_safety.html
175
176         Probably the most interesting point here is that when you
177         implement the basic guarantee, the strong guarantee often
178         comes for free. For example, in our Stack implementation,
179         almost everything we did was needed to satisfy just the basic
180         guarantee -- and what's presented above very nearly satisfies
181         the strong guarantee, with little of no extra work. Not half
182         bad, considering all the trouble we went to.
183
184         In addition to these two guarantees, there is one more
185         guarantee that certain functions must provide in order to make
186         overall exception safety possible:
187
188 3. Nothrow guarantee: The function will not emit an exception under any
189         circumstances.
190         Overall exception safety isn't possible unless certain
191         functions are guaranteed not to throw. In particular, we've
192         seen that this is true for destructors; later in this
193         miniseries, we'll see that it's also needed in certain helper
194         functions, such as Swap().
195 "
196
197 For all cases where we might be able to write exception safe functions
198 without using try, throw or catch we should do so. In particular we
199 should look over all destructors to ensure that they are as exception
200 safe as possible.
201
202 Later when more compiler support exceptions sufficiently well we will
203 begin using them too. One reason for this is that the C++ standard
204 library actually requires exceptions, e.g. "new" will throw
205 bad_allocation if the requested memory is not available.
206
207
208 Formatting
209 ----------
210
211 * Only one declaration on each line.
212         int a;
213         int b;
214         -NOT-
215         int a, b; // wrong
216   This is especially important when initialization is done at the same
217   time:
218         string a("Lars");
219         string b("Gullik");
220         -NOT-
221         string a("Lars"), b("Gullik"); // wrong
222
223 * Pointers and references
224         char * p = "flop";
225         char & c = *p;
226         -NOT-
227         char *p = "flop"; // wrong
228         char &c = *p;     // wrong
229
230   Some time ago we had a huge discussion on this subject and after
231   convincing argumentation from Asger this is what we decided. Also note
232   that we will have:
233         char const * p;
234         -NOT-
235         const char * p; // wrong
236
237 * Operator names and parentheses
238         operator==(type)
239         -NOT-
240         operator == (type)  // wrong
241
242   The == is part of the function name, separating it makes the
243   declaration look like an expression.
244
245 * Function names and parentheses
246         void mangle()
247         -NOT-
248         void mangle ()  // wrong
249
250 * Enumerators
251         enum {
252                 one = 1,
253                 two = 2,
254                 three = 3
255         };
256         -NOT-
257         enum { one = 1, two = 2, three 3 }; // wrong
258         -NOT-
259         enum {
260                 ONE = 1,
261                 TWO = 2,
262                 THREE = 3
263         };
264
265 * Naming rules for classes
266
267   - Use descriptive but simple and short names. For stuff specific to LyX
268     use LyX as prefix. Some modules, like mathed or spellchecker, could have
269     other prefixes.
270     [I am not so sure about the LyX prefix]
271
272   - Class names are usually capitalized, and function names lowercased.
273     Enums are named like Classes, values are usually in lower-case.
274
275   - Long variables are named like thisLongVariableName.
276
277   New types are capitalized, so this goes for typedefs, classes, structs
278   and enums.
279
280 * Formatting
281
282   - Adapt the formatting of your code to the one used in the
283     other parts of LyX. In case there is different formatting for
284     the same construct, use the one used more often.
285
286 * Use existing structures
287
288   - Use string wherever possible. LyX will someday move to Unicode, and
289     that will be easy if everybody uses string now.
290
291   - Check out the filename and path tools in filetools.h
292
293   - Check out the string tools in lstring.h, and the SubString class
294     and the regex class.
295
296   - Use the DebugStream class to report errors and messages using
297     the lyxerr instantiation.
298
299   [add description of other existing structures]
300
301
302 * Declarations
303
304   - Use this order for the access sections of your class: public,
305     protected, private. The public section is interesting for every
306     user of the class. The private section is only of interest for the
307     implementors of the class (you). [Obviously not true since this is
308     for developers, and we do not want one developer only to be able to
309     read and understand the implementation of class internals. Lgb]
310
311   - Avoid declaring global objects in the declaration file of the class.
312     If the same variable is used for all objects, use a static member.
313
314   - Avoid global or static variables. An exception to this rule is
315     very private stuff like the math stack.
316
317
318 * File headers
319
320   - If you create a new file, the top of the file should look something
321     like this :
322
323   /**
324    * \file NewFile.C
325    * This file is part of LyX, the document processor.
326    * Licence details can be found in the file COPYING.
327    *
328    * \author Kaiser Sose
329    *
330    * Full author contact details are available in file CREDITS
331    */
332
333 * Documentation
334
335   - The documentation is generated from the header files.
336   - You document for the other developers, not for yourself.
337   - You should document what the function does, not the implementation.
338   - in the .C files you document the implementation.
339   - Single line description (///), multiple lines description (/** ... */)
340   - see the doxygen webpage referenced above
341
342
343 * NAMING RULES FOR USER-COMMANDS
344
345   Here's the set of rules to apply when a new command name is introduced:
346
347   1) Use the object.event order. That is, use `word-forward' instead of
348      `forward-word'.
349   2) Don't introduce an alias for an already named object. Same for events.
350   3) Forward movement or focus is called `forward' (not `right').
351   4) Backward movement or focus is called `backward' (not `left').
352   5) Upward movement of focus is called `up'.
353   6) Downward movement is called `down'.
354   7) The begin of an object is called `begin' (not `start').
355   8) The end of an object is called `end'.
356
357
358  *************************************************************
359
360  How to create class interfaces.
361  (a.k.a How Non-Member Functions Improve Encapsulation)
362  ======================================================
363
364         I recently read an article by Scott Meyers in C/C++ User's
365 Journal (Vol.18,No.2), where he makes a strong case on how non-member
366 functions makes classes more encapsulated, not less. Just skipping
367 to the core of this provides us with the following algorithm for
368 deciding what kind of function to add to a class interface:
369
370         - We need to add a function f to the class C's API.
371
372         if (f needs to be virtual)
373                 make f a member function of C;
374         else if (f is operator>> or operator<<) {
375                 make f a non-member function;
376                 if (f needs access to non-public members of C)
377                         make f a friend of C;
378         } else if (f needs type conversions on its left-most argument) {
379                 make f a non-member function;
380                 if (f needs access to non-public members of C)
381                         make f a friend of C;
382         } else if (f can be implemented via C's public interface)
383                 make f a non-member function;
384         else
385                 make f a member function of C;
386
387 (I'll fill in more from Scott Meyers article when time allows.)
388
389 References
390 ----------
391
392 [ExC++] Sutter, Herb. Exceptional C++: 47 engineering puzzles,
393         programming problems, and solutions. ISBN 0-201-61562-2