]> git.lyx.org Git - lyx.git/blob - development/coding/CodingRulesAndAdvice.lyx
27b272ce5df79d283a143396fa3811250dc6b735
[lyx.git] / development / coding / CodingRulesAndAdvice.lyx
1 #LyX 1.6.7 created this file. For more info see http://www.lyx.org/
2 \lyxformat 345
3 \begin_document
4 \begin_header
5 \textclass scrbook
6 \use_default_options true
7 \language english
8 \inputencoding auto
9 \font_roman default
10 \font_sans default
11 \font_typewriter default
12 \font_default_family default
13 \font_sc false
14 \font_osf false
15 \font_sf_scale 100
16 \font_tt_scale 100
17
18 \graphics default
19 \paperfontsize default
20 \spacing single
21 \use_hyperref false
22 \papersize default
23 \use_geometry false
24 \use_amsmath 1
25 \use_esint 1
26 \cite_engine basic
27 \use_bibtopic false
28 \paperorientation portrait
29 \secnumdepth 3
30 \tocdepth 3
31 \paragraph_separation indent
32 \defskip medskip
33 \quotes_language english
34 \papercolumns 1
35 \papersides 1
36 \paperpagestyle default
37 \listings_params "basicstyle={\footnotesize}"
38 \tracking_changes false
39 \output_changes false
40 \author "" 
41 \author "" 
42 \end_header
43
44 \begin_body
45
46 \begin_layout Title
47 LyX Development
48 \begin_inset Newline newline
49 \end_inset
50
51 Rules and Recommendations
52 \end_layout
53
54 \begin_layout Chapter
55 Rules for the code in LyX
56 \begin_inset Foot
57 status collapsed
58
59 \begin_layout Plain Layout
60 Updated from the C++STYLE distributed with the GNU C++ Standard.
61 \end_layout
62
63 \end_inset
64
65
66 \end_layout
67
68 \begin_layout Standard
69 The aim of this file is to serve as a guide for the developers, to aid us
70  to get clean and uniform code.
71  This document is incomplete.
72  We really like to have new developers joining the LyX Project.
73  However, we have had problems in the past with developers leaving the project
74  and their contributed code in a far from perfect state.
75  Most of this happened before we really became aware of these issues, but
76  still, we don't want it to happen again.
77  So we have put together some guidelines and rules for the developers.
78 \end_layout
79
80 \begin_layout Section
81 General
82 \end_layout
83
84 \begin_layout Standard
85 These guidelines should save us a lot of work while cleaning up the code
86  and help us to have quality code.
87  LyX has been haunted by problems coming from unfinished projects by people
88  who have left the team.
89  Those problems will hopefully disappear if the code is easy to hand over
90  to somebody else.
91  In general, if you want to contribute to the main source, we expect at
92  least that you:
93 \end_layout
94
95 \begin_layout Itemize
96 the most important rule first: KISS (Keep It Simple Stupid), always use
97  a simple implementation in favor of a more complicated one.
98  This eases maintenance a lot.
99 \end_layout
100
101 \begin_layout Itemize
102 write good C++ code: Readable, well commented and taking advantage of the
103  OO model.
104  Follow the formatting guidelines.
105  See Formatting.
106 \end_layout
107
108 \begin_layout Itemize
109 adapt the code to the structures already existing in LyX, or in the case
110  that you have better ideas, discuss them on the developer's list before
111  writing the code.
112 \end_layout
113
114 \begin_layout Itemize
115 take advantage of the C++ standard library.
116  Especially don't use custom containers when a standard container is usable;
117  learn to use the algorithms and functors in the standard library.
118 \end_layout
119
120 \begin_layout Itemize
121 be aware of exceptions and write exception safe code.
122  See Exceptions.
123 \end_layout
124
125 \begin_layout Itemize
126 document all variables, methods, functions, classes etc.
127  We are using the source documentation program doxygen, a program that handles
128  javadoc syntax, to document sources.
129  You can download doxygen from: http://www.stack.nl/~dimitri/doxygen/
130 \end_layout
131
132 \begin_layout Itemize
133 we have certain code constructs that we try to follow.
134  See Code Constructs.
135 \end_layout
136
137 \begin_layout Section
138 Submitting Code
139 \end_layout
140
141 \begin_layout Standard
142 It is implicitly understood that all patches contributed to The LyX Project
143  is under the Gnu General Public License, version 2 or later.
144  If you have a problem with that, don't contribute code.
145  Also please don't just pop up out of the blue with a huge patch (or small)
146  that changes something substantial in LyX.
147  Always discuss your ideas with the developers on the developer's mailing
148  list.
149  When you create the patch, please use "diff -up" since we find that a lot
150  easier to read than the other diff formats.
151  Also please do not send patches that implements or fixes several different
152  things; several patches is a much better option.
153  We also require you to provide a commit message entry with every patch,
154  this describes in detail what the patch is doing.
155  
156 \end_layout
157
158 \begin_layout Section
159 Code Constructs
160 \end_layout
161
162 \begin_layout Standard
163 We have several guidelines on code constructs, some of these exist to make
164  the code faster, others to make the code clearer.
165  Yet others exist to allow us to take advantage of the strong type checking
166  in C++.
167  
168 \end_layout
169
170 \begin_layout Itemize
171 Declaration of variables should wait as long as possible.
172  The rule is: "Don't declare it until you need it." In C++ there are a lot
173  of user defined types, and these can very often be expensive to initialize.
174  This rule connects to the next rule too.
175  
176 \end_layout
177
178 \begin_layout Itemize
179 Declare the variable as const if you don't need to change it.
180  This applies to POD types like int as well as classes.
181  
182 \end_layout
183
184 \begin_layout Itemize
185 Make the scope of a variable as small as possible.
186 \end_layout
187
188 \begin_layout Itemize
189 Make good use of namespaces.
190  Prefer anonymous namespaces to declaring "static" for file scope.
191 \end_layout
192
193 \begin_layout Itemize
194 Prefer preincrement to postincrement whenever possible.
195 \end_layout
196
197 \begin_layout Itemize
198 Preincrement has potential of being faster than postincrement.
199  Just think about the obvious implementations of pre/post-increment.
200  This rule applies to decrement too.
201 \end_layout
202
203 \begin_layout Itemize
204 Use:
205 \end_layout
206
207 \begin_deeper
208 \begin_layout Standard
209 \begin_inset listings
210 lstparams "basicstyle={\footnotesize},language={C++}"
211 inline false
212 status open
213
214 \begin_layout Plain Layout
215
216 ++T;
217 \end_layout
218
219 \begin_layout Plain Layout
220
221 --U;
222 \end_layout
223
224 \end_inset
225
226
227 \end_layout
228
229 \begin_layout Standard
230 Do not use:
231 \end_layout
232
233 \begin_layout Standard
234 \begin_inset listings
235 inline false
236 status open
237
238 \begin_layout Plain Layout
239
240 T++; // not used in LyX
241 \end_layout
242
243 \begin_layout Plain Layout
244
245 U--;// not used in LyX
246 \end_layout
247
248 \end_inset
249
250
251 \end_layout
252
253 \end_deeper
254 \begin_layout Itemize
255 Try to minimize evaluation of the same code over and over.
256  This is aimed especially at loops.
257  
258 \begin_inset Newline newline
259 \end_inset
260
261 Use:
262 \end_layout
263
264 \begin_deeper
265 \begin_layout Standard
266 \begin_inset listings
267 inline false
268 status open
269
270 \begin_layout Plain Layout
271
272 Container::iterator end = large.end();
273 \end_layout
274
275 \begin_layout Plain Layout
276
277 for (Container::iterator it = large.begin(); it != end; ++it) {
278 \end_layout
279
280 \begin_layout Plain Layout
281
282         ...;
283 \end_layout
284
285 \begin_layout Plain Layout
286
287 }
288 \end_layout
289
290 \end_inset
291
292
293 \end_layout
294
295 \begin_layout Standard
296 Do not use:
297 \end_layout
298
299 \begin_layout Standard
300 \begin_inset listings
301 inline false
302 status open
303
304 \begin_layout Plain Layout
305
306 for (Container::iterator it = large.begin(); it != large.end(); ++it) {
307 \end_layout
308
309 \begin_layout Plain Layout
310
311         ...;
312 \end_layout
313
314 \begin_layout Plain Layout
315
316 }
317 \end_layout
318
319 \end_inset
320
321
322 \end_layout
323
324 \end_deeper
325 \begin_layout Itemize
326 For functions and methods that return a non-POD type
327 \begin_inset Foot
328 status open
329
330 \begin_layout Plain Layout
331 Plain Ol' Data type
332 \end_layout
333
334 \end_inset
335
336  T, return T const instead.
337  This gives better type checking, and will give a compiler warning when
338  temporaries are used wrongly.
339 \end_layout
340
341 \begin_deeper
342 \begin_layout Standard
343 Use:
344 \end_layout
345
346 \begin_layout Standard
347 \begin_inset listings
348 inline false
349 status open
350
351 \begin_layout Plain Layout
352
353 T const add(..);
354 \end_layout
355
356 \end_inset
357
358
359 \end_layout
360
361 \begin_layout Standard
362 Do not use:
363 \end_layout
364
365 \begin_layout Standard
366 \begin_inset listings
367 inline false
368 status open
369
370 \begin_layout Plain Layout
371
372 T add(..);
373 \end_layout
374
375 \end_inset
376
377
378 \end_layout
379
380 \end_deeper
381 \begin_layout Itemize
382 Avoid using the default cases in switch statements unless you have too.
383  Use the correct type for the switch expression and let the compiler ensure
384  that all cases are exhausted.
385 \end_layout
386
387 \begin_layout Itemize
388 \begin_inset listings
389 inline false
390 status open
391
392 \begin_layout Plain Layout
393
394 enum Foo {
395 \end_layout
396
397 \begin_layout Plain Layout
398
399         FOO_BAR1,
400 \end_layout
401
402 \begin_layout Plain Layout
403
404         FOO_BAR2
405 \end_layout
406
407 \begin_layout Plain Layout
408
409 };
410 \end_layout
411
412 \begin_layout Plain Layout
413
414 \end_layout
415
416 \begin_layout Plain Layout
417
418 Foo f = ...;
419 \end_layout
420
421 \begin_layout Plain Layout
422
423 \end_layout
424
425 \begin_layout Plain Layout
426
427 switch (f) {
428 \end_layout
429
430 \begin_layout Plain Layout
431
432         case FOO_BAR1: ...; 
433 \end_layout
434
435 \begin_layout Plain Layout
436
437                 break;
438 \end_layout
439
440 \begin_layout Plain Layout
441
442         case FOO_BAR2: ...; 
443 \end_layout
444
445 \begin_layout Plain Layout
446
447                 break;
448 \end_layout
449
450 \begin_layout Plain Layout
451
452         default: ...; 
453 \end_layout
454
455 \begin_layout Plain Layout
456
457                 // not needed and would shadow a wrong use of Foo
458 \end_layout
459
460 \begin_layout Plain Layout
461
462                 break; 
463 \end_layout
464
465 \begin_layout Plain Layout
466
467 }
468 \end_layout
469
470 \end_inset
471
472
473 \end_layout
474
475 \begin_layout Section
476 Exceptions
477 \end_layout
478
479 \begin_layout Standard
480 Be aware of the presence of exceptions.
481  One important thing to realize is that you often do not have to use throw,
482  try or catch to be exception safe.
483  Let's look at the different types of exceptions safety: (These are taken
484  from Herb Sutter's book[ExC++] 
485 \end_layout
486
487 \begin_layout Enumerate
488 Basic guarantee: Even in the presence of exceptions thrown by T or other
489  exceptions, Stack objects don't leak resources.
490  Note that this also implies that the container will be destructible and
491  usable even if an exception is thrown while performing some container operation.
492  However, if an exception is thrown, the container will be in a consistent,
493  but not necessarily predictable, state.
494  Containers that support the basic guarantee can work safely in some settings.
495  
496 \end_layout
497
498 \begin_layout Enumerate
499 Strong guarantee: If an operation terminates because of an exception, program
500  state will remain unchanged.
501  This always implies commit-or-rollback semantics, including that no references
502  or iterators into the container be invalidated if an operation fails.
503  For example, if a Stack client calls Top and then attempts a Push that
504  fails because of an exception, then the state of the Stack object must
505  be unchanged and the reference returned from the prior call to Top must
506  still be valid.
507  For more information on these guarantees, see Dave Abrahams's documentation
508  of the SGI exception-safe standard library adaption at: http://www.stlport.org/do
509 c/exception_safety.html Probably the most interesting point here is that
510  when you implement the basic guarantee, the strong guarantee often comes
511  for free.
512  For example, in our Stack implementation, almost everything we did was
513  needed to satisfy just the basic guarantee -- and what's presented above
514  very nearly satisfies the strong guarantee, with little of no extra work.
515  Not half bad, considering all the trouble we went to.
516  In addition to these two guarantees, there is one more guarantee that certain
517  functions must provide in order to make overall exception safety possible:
518 \end_layout
519
520 \begin_layout Enumerate
521 No throw guarantee: The function will not emit an exception under any circumstan
522 ces.
523  Overall exception safety isn't possible unless certain functions are guaranteed
524  not to throw.
525  In particular, we've seen that this is true for destructors; later in this
526  miniseries, we'll see that it's also needed in certain helper functions,
527  such as Swap().
528 \end_layout
529
530 \begin_layout Standard
531 For all cases where we might be able to write exception safe functions without
532  using try, throw or catch we should do so.
533  In particular we should look over all destructors to ensure that they are
534  as exception safe as possible.
535 \end_layout
536
537 \begin_layout Section
538 Formatting
539 \end_layout
540
541 \begin_layout Itemize
542 Only one declaration on each line.
543 \end_layout
544
545 \begin_deeper
546 \begin_layout Standard
547 Use:
548 \end_layout
549
550 \begin_layout Standard
551 \begin_inset listings
552 inline false
553 status open
554
555 \begin_layout Plain Layout
556
557 int a;
558 \end_layout
559
560 \begin_layout Plain Layout
561
562 int b;
563 \end_layout
564
565 \end_inset
566
567
568 \end_layout
569
570 \begin_layout Standard
571 Do not use:
572 \end_layout
573
574 \begin_layout Standard
575 \begin_inset listings
576 inline false
577 status open
578
579 \begin_layout Plain Layout
580
581 int a,b; // not used in LyX
582 \end_layout
583
584 \end_inset
585
586
587 \end_layout
588
589 \begin_layout Standard
590 This is especially important when initialization is done at the same time:
591 \end_layout
592
593 \begin_layout Standard
594 Use:
595 \end_layout
596
597 \begin_layout Standard
598 \begin_inset listings
599 inline false
600 status open
601
602 \begin_layout Plain Layout
603
604 string a = "Lars";
605 \end_layout
606
607 \begin_layout Plain Layout
608
609 string b = "Gullik";
610 \end_layout
611
612 \end_inset
613
614
615 \end_layout
616
617 \begin_layout Standard
618 Do not use:
619 \end_layout
620
621 \begin_layout Standard
622 \begin_inset listings
623 inline false
624 status open
625
626 \begin_layout Plain Layout
627
628 string a = "Lars", b = "Gullik"; // not used in LyX
629 \end_layout
630
631 \end_inset
632
633
634 \end_layout
635
636 \begin_layout Standard
637 [Note that 'string a = "Lars"' is formally calling a copy constructor on
638  a temporary constructed from a string literal and therefore has the potential
639  of being more expensive then direct construction by 'string a("Lars")'.
640  However the compiler is allowed to elide the copy (even if it had side
641  effects), and modern compilers typically do so.
642  Given these equal costs, LyX code favours the '=' idiom as it is in line
643  with the traditional C-style initialization, _and_ cannot be mistaken as
644  function declaration, _and_ reduces the level of nested parantheses in
645  more initializations.]
646 \end_layout
647
648 \end_deeper
649 \begin_layout Itemize
650 Pointers and references:
651 \end_layout
652
653 \begin_deeper
654 \begin_layout Standard
655 Use:
656 \end_layout
657
658 \begin_layout Standard
659 \begin_inset listings
660 inline false
661 status open
662
663 \begin_layout Plain Layout
664
665 char * p = "flop";
666 \end_layout
667
668 \begin_layout Plain Layout
669
670 char & c = *p;
671 \end_layout
672
673 \end_inset
674
675
676 \end_layout
677
678 \begin_layout Standard
679 Do not use:
680 \end_layout
681
682 \begin_layout Standard
683 \begin_inset listings
684 inline false
685 status open
686
687 \begin_layout Plain Layout
688
689 char *p = "flop"; // not used in LyX
690 \end_layout
691
692 \begin_layout Plain Layout
693
694 char &c = *p; // not used in LyX
695 \end_layout
696
697 \end_inset
698
699
700 \end_layout
701
702 \begin_layout Standard
703 Some time ago we had a huge discussion on this subject and after convincing
704  argumentation from Asger this is what we decided.
705  Also note that we will have:
706 \end_layout
707
708 \begin_layout Standard
709 \begin_inset listings
710 inline false
711 status open
712
713 \begin_layout Plain Layout
714
715 char const * p;
716 \end_layout
717
718 \end_inset
719
720
721 \end_layout
722
723 \begin_layout Standard
724 and not
725 \end_layout
726
727 \begin_layout Standard
728 \begin_inset listings
729 inline false
730 status open
731
732 \begin_layout Plain Layout
733
734 const char * p; // not used in LyX
735 \end_layout
736
737 \end_inset
738
739
740 \end_layout
741
742 \end_deeper
743 \begin_layout Itemize
744 Operator names and parentheses
745 \end_layout
746
747 \begin_deeper
748 \begin_layout Standard
749 \begin_inset listings
750 inline false
751 status open
752
753 \begin_layout Plain Layout
754
755 operator==(type)
756 \end_layout
757
758 \end_inset
759
760
761 \end_layout
762
763 \begin_layout Standard
764 and not
765 \end_layout
766
767 \begin_layout Standard
768 \begin_inset listings
769 inline false
770 status open
771
772 \begin_layout Plain Layout
773
774 operator == (type) // not used in LyX
775 \end_layout
776
777 \end_inset
778
779
780 \end_layout
781
782 \begin_layout Standard
783 The == is part of the function name, separating it makes the declaration
784  look like an expression.
785 \end_layout
786
787 \end_deeper
788 \begin_layout Itemize
789 Function names and parentheses
790 \end_layout
791
792 \begin_deeper
793 \begin_layout Standard
794 \begin_inset listings
795 inline false
796 status open
797
798 \begin_layout Plain Layout
799
800 void mangle()
801 \end_layout
802
803 \end_inset
804
805
806 \end_layout
807
808 \begin_layout Standard
809 and not
810 \end_layout
811
812 \begin_layout Standard
813 \begin_inset listings
814 inline false
815 status open
816
817 \begin_layout Plain Layout
818
819 void mangle () // not used in LyX
820 \end_layout
821
822 \end_inset
823
824
825 \end_layout
826
827 \end_deeper
828 \begin_layout Itemize
829 Enumerators
830 \end_layout
831
832 \begin_deeper
833 \begin_layout Standard
834 \begin_inset listings
835 inline false
836 status open
837
838 \begin_layout Plain Layout
839
840 enum Foo {
841 \end_layout
842
843 \begin_layout Plain Layout
844
845         FOO_ONE = 1,
846 \end_layout
847
848 \begin_layout Plain Layout
849
850         FOO_TWO = 2,
851 \end_layout
852
853 \begin_layout Plain Layout
854
855         FOO_THREE = 3
856 \end_layout
857
858 \begin_layout Plain Layout
859
860 };
861 \end_layout
862
863 \end_inset
864
865
866 \end_layout
867
868 \begin_layout Standard
869 and not
870 \end_layout
871
872 \begin_layout Standard
873 \begin_inset listings
874 inline false
875 status open
876
877 \begin_layout Plain Layout
878
879 enum { one = 1, two = 2, three 3 }; // not used in LyX
880 \end_layout
881
882 \end_inset
883
884
885 \end_layout
886
887 \begin_layout Standard
888 and not
889 \end_layout
890
891 \begin_layout Standard
892 \begin_inset listings
893 inline false
894 status open
895
896 \begin_layout Plain Layout
897
898 enum {
899 \end_layout
900
901 \begin_layout Plain Layout
902
903 One = 1,
904 \end_layout
905
906 \begin_layout Plain Layout
907
908 Two = 2,
909 \end_layout
910
911 \begin_layout Plain Layout
912
913 Three = 3
914 \end_layout
915
916 \begin_layout Plain Layout
917
918 };
919 \end_layout
920
921 \end_inset
922
923
924 \end_layout
925
926 \end_deeper
927 \begin_layout Itemize
928 Null pointers
929 \end_layout
930
931 \begin_deeper
932 \begin_layout Standard
933 Using a plain 0 is always correct and least effort to type.
934  So: 
935 \end_layout
936
937 \begin_layout Standard
938 \begin_inset listings
939 inline false
940 status open
941
942 \begin_layout Plain Layout
943
944 void * p = 0;
945 \end_layout
946
947 \end_inset
948
949
950 \end_layout
951
952 \begin_layout Standard
953 and not
954 \end_layout
955
956 \begin_layout Standard
957 \begin_inset listings
958 inline false
959 status open
960
961 \begin_layout Plain Layout
962
963 void * p = NULL; // not used in LyX
964 \end_layout
965
966 \end_inset
967
968
969 \end_layout
970
971 \begin_layout Standard
972 and not
973 \end_layout
974
975 \begin_layout Standard
976 \begin_inset listings
977 inline false
978 status open
979
980 \begin_layout Plain Layout
981
982 void * p = '
983 \backslash
984 0'; // not used in LyX
985 \end_layout
986
987 \end_inset
988
989
990 \end_layout
991
992 \begin_layout Standard
993 and not
994 \end_layout
995
996 \begin_layout Standard
997 \begin_inset listings
998 inline false
999 status open
1000
1001 \begin_layout Plain Layout
1002
1003 void * p = 42 - 7 * 6; // not used in LyX
1004 \end_layout
1005
1006 \end_inset
1007
1008
1009 \end_layout
1010
1011 \begin_layout Standard
1012 Note: As an exception, imported third party code as well as code interfacing
1013  the "native" APIs (src/support/os_*) can use NULL.
1014 \end_layout
1015
1016 \end_deeper
1017 \begin_layout Itemize
1018 Naming rules for classes
1019 \end_layout
1020
1021 \begin_deeper
1022 \begin_layout Itemize
1023 Use descriptive but simple and short names.
1024  Do not abbreviate.
1025 \end_layout
1026
1027 \begin_layout Itemize
1028 Class names are usually capitalized, and function names lowercased.
1029 \end_layout
1030
1031 \begin_layout Itemize
1032 Enums are named like Classes, values are usually in lower-case.
1033 \end_layout
1034
1035 \begin_layout Itemize
1036 Public API is camel-case ('void setAFlagToAValue(bool)')
1037 \end_layout
1038
1039 \begin_layout Itemize
1040 Members variables are underscored ('enable_this_feature_flag_') with a final
1041  '_'
1042 \end_layout
1043
1044 \begin_layout Itemize
1045 Private/protected functions are also camel-case
1046 \end_layout
1047
1048 \begin_layout Itemize
1049 New types are capitalized, so this goes for typedefs, classes, structs and
1050  enums.
1051 \end_layout
1052
1053 \end_deeper
1054 \begin_layout Itemize
1055 Formatting
1056 \end_layout
1057
1058 \begin_deeper
1059 \begin_layout Itemize
1060 Adapt the formatting of your code to the one used in the other parts of
1061  LyX.
1062  In case there is different formatting for the same construct, use the one
1063  used more often.
1064 \end_layout
1065
1066 \end_deeper
1067 \begin_layout Itemize
1068 Use existing structures
1069 \end_layout
1070
1071 \begin_deeper
1072 \begin_layout Itemize
1073 Use string wherever possible.
1074  LyX will someday move to Unicode, and that will be easy if everybody uses
1075  string now.
1076  Unicode strings should prefer using docstring instead of UTF-8 encoded
1077  std::string.
1078 \end_layout
1079
1080 \begin_layout Itemize
1081 Check out the filename and path tools in filetools.h
1082 \end_layout
1083
1084 \begin_layout Itemize
1085 Check out the string tools in lstring.h.
1086 \end_layout
1087
1088 \begin_layout Itemize
1089 Use the LyXErr class to report errors and messages using the lyxerr instantiatio
1090 n.
1091  [add description of other existing structures]
1092 \end_layout
1093
1094 \end_deeper
1095 \begin_layout Itemize
1096 Declarations
1097 \end_layout
1098
1099 \begin_deeper
1100 \begin_layout Itemize
1101 Use this order for the access sections of your class: public, protected,
1102  private.
1103  The public section is interesting for every user of the class.
1104  The private section is only of interest for the implementors of the class
1105  (you).
1106  [Obviously not true since this is for developers, and we do not want one
1107  developer only to be able to read and understand the implementation of
1108  class internals.
1109  Lgb]
1110 \end_layout
1111
1112 \begin_layout Itemize
1113 Avoid declaring global objects in the declaration file of the class.
1114  If the same variable is used for all objects, use a static member.
1115 \end_layout
1116
1117 \begin_layout Itemize
1118 Avoid global or static variables.
1119 \end_layout
1120
1121 \end_deeper
1122 \begin_layout Itemize
1123 File headers
1124 \end_layout
1125
1126 \begin_deeper
1127 \begin_layout Standard
1128 If you create a new file, the top of the file should look something like
1129  this :
1130 \end_layout
1131
1132 \begin_layout Standard
1133 \begin_inset listings
1134 inline false
1135 status open
1136
1137 \begin_layout Plain Layout
1138
1139 /**
1140 \end_layout
1141
1142 \begin_layout Plain Layout
1143
1144
1145 \backslash
1146 file NewFile.cpp
1147 \end_layout
1148
1149 \begin_layout Plain Layout
1150
1151 * This file is part of LyX, the document processor.
1152 \end_layout
1153
1154 \begin_layout Plain Layout
1155
1156 * Licence details can be found in the file COPYING.
1157 \end_layout
1158
1159 \begin_layout Plain Layout
1160
1161 *
1162 \end_layout
1163
1164 \begin_layout Plain Layout
1165
1166
1167 \backslash
1168 author Kaiser Sose
1169 \end_layout
1170
1171 \begin_layout Plain Layout
1172
1173 *
1174 \end_layout
1175
1176 \begin_layout Plain Layout
1177
1178 * Full author contact details are available in file CREDITS
1179 \end_layout
1180
1181 \begin_layout Plain Layout
1182
1183 */
1184 \end_layout
1185
1186 \end_inset
1187
1188
1189 \end_layout
1190
1191 \end_deeper
1192 \begin_layout Itemize
1193 Documentation
1194 \end_layout
1195
1196 \begin_deeper
1197 \begin_layout Itemize
1198 The documentation is generated from the header files.
1199 \end_layout
1200
1201 \begin_layout Itemize
1202 You document for the other developers, not for yourself.
1203 \end_layout
1204
1205 \begin_layout Itemize
1206 You should document what the function does, not the implementation.
1207 \end_layout
1208
1209 \begin_deeper
1210 \begin_layout Itemize
1211 in the .cpp files you document the implementation.
1212 \end_layout
1213
1214 \end_deeper
1215 \begin_layout Itemize
1216 Single line description (///), multiple lines description (/** ...
1217  */) see the doxygen webpage referenced above
1218 \end_layout
1219
1220 \end_deeper
1221 \begin_layout Section
1222 Naming rules for Lyx User Functions (LFUNs)
1223 \end_layout
1224
1225 \begin_layout Standard
1226 Here is the set of rules to apply when a new command name is introduced:
1227 \end_layout
1228
1229 \begin_layout Enumerate
1230 Use the object.event order.
1231  That is, use `word-forward' instead of`forward-word'.
1232 \end_layout
1233
1234 \begin_layout Enumerate
1235 Don't introduce an alias for an already named object.
1236  Same for events.
1237 \end_layout
1238
1239 \begin_layout Enumerate
1240 Forward movement or focus is called `forward' (not `right').
1241 \end_layout
1242
1243 \begin_layout Enumerate
1244 Backward movement or focus is called `backward' (not `left').
1245 \end_layout
1246
1247 \begin_layout Enumerate
1248 Upward movement of focus is called `up'.
1249 \end_layout
1250
1251 \begin_layout Enumerate
1252 Downward movement is called `down'.
1253 \end_layout
1254
1255 \begin_layout Enumerate
1256 The begin of an object is called `begin' (not `start').
1257 \end_layout
1258
1259 \begin_layout Enumerate
1260 The end of an object is called `end'.
1261 \end_layout
1262
1263 \begin_layout Section
1264 How to create class interfaces
1265 \end_layout
1266
1267 \begin_layout Standard
1268 (a.k.a How Non-Member Functions Improve Encapsulation)
1269 \end_layout
1270
1271 \begin_layout Standard
1272 I recently read an article by Scott Meyers in , where he makes a strong
1273  case on how non-member functions makes classes more encapsulated, not less.
1274  Just skipping to the core of this provides us with the following algorithm
1275  for deciding what kind of function to add to a class interface:
1276 \end_layout
1277
1278 \begin_layout Itemize
1279 We need to add a function f to the class C's API.
1280 \end_layout
1281
1282 \begin_deeper
1283 \begin_layout Standard
1284 \begin_inset listings
1285 inline false
1286 status open
1287
1288 \begin_layout Plain Layout
1289
1290 if (f needs to be virtual)
1291 \end_layout
1292
1293 \begin_layout Plain Layout
1294
1295         make f a member function of C;
1296 \end_layout
1297
1298 \begin_layout Plain Layout
1299
1300 else if (f is operator>> or operator<<) {
1301 \end_layout
1302
1303 \begin_layout Plain Layout
1304
1305         make f a non-member function;
1306 \end_layout
1307
1308 \begin_layout Plain Layout
1309
1310         if (f needs access to non-public members of C)
1311 \end_layout
1312
1313 \begin_layout Plain Layout
1314
1315                 make f a friend of C;
1316 \end_layout
1317
1318 \begin_layout Plain Layout
1319
1320 } else if (f needs type conversions on its left-most argument) {
1321 \end_layout
1322
1323 \begin_layout Plain Layout
1324
1325         make f a non-member function;
1326 \end_layout
1327
1328 \begin_layout Plain Layout
1329
1330         if (f needs access to non-public members of C)
1331 \end_layout
1332
1333 \begin_layout Plain Layout
1334
1335                 make f a friend of C;
1336 \end_layout
1337
1338 \begin_layout Plain Layout
1339
1340 } else if (f can be implemented via C's public interface)
1341 \end_layout
1342
1343 \begin_layout Plain Layout
1344
1345         make f a non-member function;
1346 \end_layout
1347
1348 \begin_layout Plain Layout
1349
1350 else
1351 \end_layout
1352
1353 \begin_layout Plain Layout
1354
1355         make f a member function of C;
1356 \end_layout
1357
1358 \end_inset
1359
1360
1361 \end_layout
1362
1363 \end_deeper
1364 \begin_layout Chapter
1365 Recommendations
1366 \end_layout
1367
1368 \begin_layout Standard
1369 These are some rules for effective C++ programming.
1370  These are taken from Scott Meyers
1371 \begin_inset CommandInset citation
1372 LatexCommand cite
1373 key "key-4"
1374
1375 \end_inset
1376
1377 , and are presented in their short form.
1378  These are not all the rules Meyers presents, only the most important of
1379  them.
1380  LyX does not yet follow these rules, but they should be the goal.
1381 \end_layout
1382
1383 \begin_layout Itemize
1384 use const and inline instead of #define
1385 \end_layout
1386
1387 \begin_layout Itemize
1388 use the same form in corresponding calls to new and delete, i.e.
1389  write delete[] obj; if new obj[n]; was used to create the object and write
1390  delete obj; if you wrote new obj; Notice strings should be std::string's
1391  instead of char *'s.
1392 \end_layout
1393
1394 \begin_layout Itemize
1395 define a default constructor, copy constructor and an assignment operator
1396  for all classes with dynamically allocated memory that are not made noncopyable
1397 \end_layout
1398
1399 \begin_layout Itemize
1400 do not define default constructor, copy constructor and an assignment operator
1401  if the compiler generated one would do the same
1402 \end_layout
1403
1404 \begin_layout Itemize
1405 make destructors virtual in base classes and only there 
1406 \end_layout
1407
1408 \begin_layout Itemize
1409 assign to all data members in operator=()
1410 \end_layout
1411
1412 \begin_layout Itemize
1413 strive for class interfaces that are complete and minimal
1414 \end_layout
1415
1416 \begin_layout Itemize
1417 differentiate among member functions, global functions and friend functions
1418 \end_layout
1419
1420 \begin_layout Itemize
1421 avoid data members in the public interface
1422 \end_layout
1423
1424 \begin_layout Itemize
1425 use const whenever possible
1426 \end_layout
1427
1428 \begin_layout Itemize
1429 pass and return objects by reference instead of by value
1430 \end_layout
1431
1432 \begin_layout Itemize
1433 choose carefully between function overloading and parameter defaulting
1434 \end_layout
1435
1436 \begin_layout Itemize
1437 never return a reference to a local object or a dereferenced pointer initialized
1438  by new within the function
1439 \end_layout
1440
1441 \begin_layout Itemize
1442 use enums for integral constants
1443 \end_layout
1444
1445 \begin_layout Itemize
1446 minimize compilation dependencies between files
1447 \end_layout
1448
1449 \begin_layout Itemize
1450 pay attention to compiler warnings
1451 \end_layout
1452
1453 \begin_layout Itemize
1454 differentiate between inheritance of interface and inheritance of implementation
1455 \end_layout
1456
1457 \begin_layout Itemize
1458 differentiate between inheritance and templates
1459 \end_layout
1460
1461 \begin_layout Itemize
1462 ensure that global objects are initialized before they are used
1463 \end_layout
1464
1465 \begin_layout Itemize
1466 avoid conditions to 'if' and 'while' that span more than a line
1467 \end_layout
1468
1469 \begin_layout Chapter
1470 \start_of_appendix
1471 Notes
1472 \end_layout
1473
1474 \begin_layout Itemize
1475 And one of mine: (Lgb)
1476 \end_layout
1477
1478 \begin_deeper
1479 \begin_layout Itemize
1480 when swiching on enums, refrain from using "default:" if possible
1481 \end_layout
1482
1483 \end_deeper
1484 \begin_layout Itemize
1485 And one of mine: (Andre')
1486 \end_layout
1487
1488 \begin_deeper
1489 \begin_layout Itemize
1490 try to implement your class in a way that the automatically generated copy
1491  constructor and copy assignment work out-of-the box
1492 \end_layout
1493
1494 \begin_layout Itemize
1495 I don't have problems with using boost in the implementation _if and only
1496  if_ it provides actual benefits over less intrusive alternatives.
1497  I do have a problem with needlessly sprinkling 'boost::' over interfaces,
1498  especially if it does not add any value.
1499 \end_layout
1500
1501 \begin_deeper
1502 \begin_layout Standard
1503 Given that there seems to be an unconditional "typedef unsigned int quint32;"
1504  in qglobal.h I don't think there's any platform supported by current LyX
1505  that could not use 'unsigned int' (and an static assert in some implementation
1506  file for the unlikely case some ILP64 zombie raises its ugly head again.
1507  And if that happens, using <cstdint> would still be a better choice...)
1508 \end_layout
1509
1510 \begin_layout Standard
1511 The idea is to create something that's not compilable as soon as the condition
1512  is violated.
1513  There are lots of possibilities to achieve this, some examples follow:
1514 \end_layout
1515
1516 \begin_layout Standard
1517 In C++0x there's a "built-in":
1518 \end_layout
1519
1520 \begin_layout Standard
1521 \begin_inset listings
1522 inline false
1523 status open
1524
1525 \begin_layout Plain Layout
1526
1527 static_assert(sizeof(int) == 4, "Funny platform")
1528 \end_layout
1529
1530 \end_inset
1531
1532
1533 \end_layout
1534
1535 \begin_layout Standard
1536 until then on namespace scope: 
1537 \end_layout
1538
1539 \begin_layout Standard
1540 \begin_inset listings
1541 inline false
1542 status open
1543
1544 \begin_layout Plain Layout
1545
1546 #include <boost/static_assert.hpp> BOOST_STATIC_ASSERT(sizeof(int) == 4)
1547 \end_layout
1548
1549 \end_inset
1550
1551
1552 \end_layout
1553
1554 \begin_layout Standard
1555 or without boost:
1556 \end_layout
1557
1558 \begin_layout Standard
1559 \begin_inset listings
1560 inline false
1561 status open
1562
1563 \begin_layout Plain Layout
1564
1565 template<bool Condition> struct static_assert_helper;
1566 \end_layout
1567
1568 \begin_layout Plain Layout
1569
1570 template <> struct static_assert_helper<true> {}; 
1571 \end_layout
1572
1573 \begin_layout Plain Layout
1574
1575 enum { dummy = sizeof(static_assert_helper<sizeof(int) == 4>)};
1576 \end_layout
1577
1578 \end_inset
1579
1580
1581 \end_layout
1582
1583 \begin_layout Standard
1584 or somewhat brutish without templates, in any function:
1585 \end_layout
1586
1587 \begin_layout Standard
1588 \begin_inset listings
1589 inline false
1590 status open
1591
1592 \begin_layout Plain Layout
1593
1594 const int d = sizeof(int) - 4;
1595 \end_layout
1596
1597 \begin_layout Plain Layout
1598
1599 switch(0) { 
1600 \end_layout
1601
1602 \begin_layout Plain Layout
1603
1604 case 0: 
1605 \end_layout
1606
1607 \begin_layout Plain Layout
1608
1609 case !(d*d): 
1610 \end_layout
1611
1612 \begin_layout Plain Layout
1613
1614 break; 
1615 \end_layout
1616
1617 \begin_layout Plain Layout
1618
1619 }
1620 \end_layout
1621
1622 \end_inset
1623
1624
1625 \end_layout
1626
1627 \begin_layout Standard
1628 Any of them in a .cpp file will break compilation as soon as sizeof(int)
1629  is not equal 4.
1630  Personally I prefer something like the third version (or the first, if
1631  using C++0x is allowed).
1632 \end_layout
1633
1634 \end_deeper
1635 \end_deeper
1636 \begin_layout Itemize
1637 And one of mine: (vfr)
1638 \end_layout
1639
1640 \begin_deeper
1641 \begin_layout Itemize
1642 On dynamics_casts 
1643 \begin_inset Flex URL
1644 status open
1645
1646 \begin_layout Plain Layout
1647
1648 http://www.lyx.org/trac/changeset/35855
1649 \end_layout
1650
1651 \end_inset
1652
1653 :
1654 \end_layout
1655
1656 \begin_deeper
1657 \begin_layout Standard
1658 A dynamic_cast is necessary when:
1659 \end_layout
1660
1661 \begin_layout Itemize
1662 the object to be casted is from an external library because we can't add
1663  Qxxx::asXxxx() to Qt e.g.:
1664 \end_layout
1665
1666 \begin_deeper
1667 \begin_layout Itemize
1668 QAbstractListModel to GuiIdListModel,
1669 \end_layout
1670
1671 \begin_layout Itemize
1672 QValidator to PathValidator,
1673 \end_layout
1674
1675 \begin_layout Itemize
1676 QWidget to TabWorkArea,
1677 \end_layout
1678
1679 \begin_layout Itemize
1680 QWidget to GuiWorkArea;
1681 \end_layout
1682
1683 \end_deeper
1684 \begin_layout Itemize
1685 the object is to be casted from an interface to the implementing class,
1686  because the Interface does not know by whom it is implemented:
1687 \end_layout
1688
1689 \begin_deeper
1690 \begin_layout Itemize
1691 ProgressInterface to GuiProgress,
1692 \end_layout
1693
1694 \begin_layout Itemize
1695 Application to GuiApplication.
1696 \end_layout
1697
1698 \end_deeper
1699 \begin_layout Standard
1700 A dynamic_cast can be replaced by:
1701 \end_layout
1702
1703 \begin_layout Itemize
1704 already existing as***Inset() functions, e.g.:
1705 \end_layout
1706
1707 \begin_deeper
1708 \begin_layout Itemize
1709 asHullInset(),
1710 \end_layout
1711
1712 \begin_layout Itemize
1713 asInsetMath()->asMacro(),
1714 \end_layout
1715
1716 \begin_layout Itemize
1717 asInsetText();
1718 \end_layout
1719
1720 \end_deeper
1721 \begin_layout Itemize
1722 A static_cast when we are sure this can't go wrong, e.g.:
1723 \end_layout
1724
1725 \begin_deeper
1726 \begin_layout Itemize
1727 we are sure that CellData::inset->clone() is an InsetTableCell,
1728 \end_layout
1729
1730 \begin_layout Itemize
1731 in cases where we explicitly check it->lyxCode().
1732 \end_layout
1733
1734 \end_deeper
1735 \end_deeper
1736 \end_deeper
1737 \begin_layout Bibliography
1738 \begin_inset CommandInset bibitem
1739 LatexCommand bibitem
1740 key "key-1"
1741
1742 \end_inset
1743
1744 S.
1745  Meyers.
1746  Effective C++, 50 Specific Ways to Improve Your Programs and Design.
1747  Addison-Wesley, 1992
1748 \end_layout
1749
1750 \begin_layout Bibliography
1751 \begin_inset CommandInset bibitem
1752 LatexCommand bibitem
1753 key "key-2"
1754
1755 \end_inset
1756
1757 Sutter, Herb.
1758  Exceptional C++: 47 engineering puzzles, programming problems, and solutions.
1759  ISBN 0-201-61562-2
1760 \end_layout
1761
1762 \begin_layout Bibliography
1763 \begin_inset CommandInset bibitem
1764 LatexCommand bibitem
1765 key "key-4"
1766
1767 \end_inset
1768
1769 Scott Meyers, C/C++ User's Journal (Vol.18,No.2)
1770 \end_layout
1771
1772 \end_body
1773 \end_document