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