0024659: misprints in draw documentation
[occt.git] / dox / dev_guides / contribution / coding_rules.md
CommitLineData
f6e968a7 1Coding Rules {#dev_guides__coding_rules}
2======================================
3
4@tableofcontents
5
6@section OCCT_RULES_SECTION_1 Introduction
7
8The purpose of this document is to define and formalize one style of programming for developers working on Open CASCADE Technology.
9The establishment of a common style facilitates understanding and maintaining code developed by more than one programmer as well as making it easier for several people to co-operate in the development of the same framework.
10In addition, following a common programming style enables the construction of tools that incorporate knowledge of these standards to help in the programming task.
11Using a consistent coding style throughout a particular module, package, or project is important because it allows people other than the author, and the author himself, to easily understand and (hopefully) maintain the code.
12Most programming styles are somewhat arbitrary, and this one is no exception. Some guidelines have been excerpted from the public domain of widely accepted practices.
13This suggests that the guide will continue to evolve over time as new ideas and enhancements are added.
14
15@subsection OCCT_RULES_SECTION_1_1 Scope of the rules in this document
16
17Rules in this document was written for C++ code.
18However, with minor exceptions due to language restrictions, them should be applied to any sources in Open CASCADE Technology framework, including:
19- C/C++
20- GLSL programs
21- OpenCL kernels
22- TCL scripts and test cases
23
24@section OCCT_RULES_SECTION_2 Naming Conventions
25
26@subsection OCCT_RULES_SECTION_2_1 General naming rules
27
28The names considered in this section are mainly those which compound the interface to Open CASCADE Technology libraries as well as source code itself.
29
30### International language [MANDATORY]
31All names are composed of English words and their abbreviations.
32Open CASCADE Technology is an open source available for international community.
33
34### Suggestive names
35Names should be suggestive or, at least, contain a suggestive part.
36Currently, there is no exact rule that would define how to generate suggestive names. However, usually names given to toolkits, packages, classes and methods are suggestive. Here are several examples:
37- Packages containing words Geom or Geom2d in their names are related to geometrical data and operations.
38- Packages containing words TopoDS or BRep in their names are related to topological data and operations.
39- In OCAF, packages that define transient, persistent data classes and drivers to map between them, have similar names prefixed by 'T', 'P', and 'M' correspondingly (e.g. TDocStd, PDocStd, MDocStd).
40- Packages ending with ...Test define Draw Harness plugins.
41- Methods starting with Get... and Set... are usually responsible for (accordingly) retrieving/storing some data.
42
43### Related names
44Names that define logically connected functionality should have the same prefix (start with the same letters) or, at least, have any other common part in them.
45As an example the method GetCoord can be given. It returns a triple of real values and is defined for directions, vectors and points. The logical connection is obvious.
46
47### Camel Case style
48Camel Case style is preferred for names.
49For example:
50
51~~~~~{.cpp}
52Standard_Integer awidthofbox; // this is bad
53Standard_Integer width_of_box; // this is bad
54Standard_Integer aWidthOfBox; // this is OK
55~~~~~
56
57@subsection OCCT_RULES_SECTION_2_2 Names of development units
58Usually unit (e.g. package) is a set of classes, methods, enumerations or any other sources implementing certain common functionality which, to the certain extent, is self contained and independent from other parts of library.
59
60### Underscores in units names [MANDATORY]
61Names of units should not contain underscores, except cases where usage of underscores is allowed explicitly.
62Usually names of files consisting Open CASCADE Technology are constructed according to the rules defined in the appropriate sections of this document.
63
64### File names extensions [MANDATORY]
65The following extensions should be used for source files, depending on their type:
66
67 .cdl - CDL declaration files
68 .cxx - C++ source files
69 .hxx - C++ header files
70 .lxx - headers with definitions of inline methods (CDL packages)
71
72@subsection OCCT_RULES_SECTION_2_3 Names of toolkits
73
74The following rules are usually used in naming of toolkits:
75
76### Prefix for toolkits names [MANDATORY]
77Toolkits names are prefixed by TK, followed by suggestive part of name explaining the domain of functionality covered by the toolkit (e.g. TKOpenGl).
78
79### Names of classes
80Usually source files located in the unit have names that start from the name of the unit, separated from remaining part of file name (if any) by underscore "_".
81For instance, names of files containing sources of C++ classes are constructed according to the following template.
82
83### Naming of C++ class files
84The following template should be used for names of files containing sources of C++ classes:
85
86 <unit-name>_<class-name>.cxx (.hxx, .cdl etc.)
87
88Files that contain sources related to whole unit are called by the name of unit with appropriate extension.
89
90### Names of functions
91The term 'function' here is defined as:
92- Any class method
93- Any package method
94- Any non-member procedure or function
95
96It is preferred to name public methods from upper case, while protected and private methods from low case.
97
98~~~~~{.cpp}
99class MyPackage_MyClass
100{
101
102public:
103
104 Standard_Integer Value() const;
105 void SetValue (const Standard_Integer theValue);
106
107private:
108
109 void setIntegerValue (const Standard_Integer theValue);
110
111};
112~~~~~
113
114@subsection OCCT_RULES_SECTION_2_4 Names of variables
115There are several rules that describe currently accepted practice used for naming variables.
116
117### Naming of variables
118Name of variable should not conflict with the global names (packages, macros, functions, global variables etc.), either existing or possible.
119The name of variable should not start with underscore(s).
120
121See the following examples:
122
123~~~~~{.cpp}
124Standard_Integer Elapsed_Time = 0; // this is bad - possible class name
125Standard_Integer gp = 0; // this is bad - existing package name
126Standard_Integer aGp = 0; // this is OK
127Standard_Integer _KERNEL = 0; // this is bad
128Standard_Integer THE_KERNEL = 0; // this is OK
129~~~~~
130
131### Names of function parameters
132The name of a function (procedure, class method) parameter should start with 'the' followed by the rest of the name starting with capital letter.
133
134See the following examples:
135
136~~~~~{.cpp}
137void Package_MyClass::MyFunction (const gp_Pnt& p); // this is bad
138void Package_MyClass::MyFunction (const gp_Pnt& theP); // this is OK
139void Package_MyClass::MyFunction (const gp_Pnt& thePoint); // this is preferred
140~~~~~
141
142### Names of class member variables
143The name of a class member variable should start with 'my' followed by the rest of the name (rule for suggestive names applies) starting with capital letter.
144
145See the following examples:
146
147~~~~~{.cpp}
148Standard_Integer counter; // This is bad
149Standard_Integer myC; // This is OK
150Standard_Integer myCounter; // This is preferred
151~~~~~
152
153### Names of global variables
154It is strongly recommended to avoid defining any global variables.
155However, as soon as global variable is necessary, the following rule applies.
156Global variable name should be prefixed by the name of a class or a package where it is defined followed with '_my'.
157
158See the following examples:
159
160~~~~~{.cpp}
161Standard_Integer MyPackage_myGlobalVariable = 0;
162Standard_Integer MyPackage_MyClass_myGlobalVariable = 0;
163~~~~~
164
165Static constants within the file should be spelled upper-case and started with 'THE_' prefix:
166~~~~~{.cpp}
167namespace
168{
169 static const Standard_Real THE_CONSTANT_COEF = 3.14;
170};
171~~~~~
172
173### Names of local variables
174Local variable name should be constructed in such way that it can be distinguished from the name of a function parameter, a class member variable and a global variable.
175It is preferred to prefix local variable names with 'a' and 'an' (also 'is', 'to' and 'has' for Boolean variables).
176
177See the following examples:
178
179~~~~~{.cpp}
180Standard_Integer theI; // this is bad
181Standard_Integer i; // this is bad
182Standard_Integer index; // this is bad
183Standard_Integer anIndex; // this is OK
184~~~~~
185
186### Avoid dummy names
187Avoid dummy names like I, j, k. Such names are meaningless and easy to mix up.
188Code becomes more and more complicated when such dummy names used multiple times in code with different meaning, in cycles with different iteration ranges and so on.
189
190See the following examples for preferred style:
191
192~~~~~{.cpp}
193void Average (const Standard_Real** theArray,
194 Standard_Integer theRowsNb,
195 Standard_Integer theRowLen,
196 Standard_Real& theResult)
197{
198 theResult = 0.0;
199 for (Standard_Integer aRow = 0; aRow < aRowsNb; ++aRow)
200 {
201 for (Standard_Integer aCol = 0; aCol < aRowLen; ++aCol)
202 {
203 theResult += theArray[aRow][aCol];
204 }
205 theResult /= Standard_Real(aRowsNb * aRowLen);
206 }
207}
208~~~~~
209
210@section OCCT_RULES_SECTION_3 Formatting rules
211
212In order to improve the open source readability and, consequently, maintainability, the following set of rules is applied.
213
214### International language [MANDATORY]
215All comments in all sources must be in English.
216
217### Line length
218In all sources try not to exceed 120 characters limit of line length.
219
220### C++ style comments
221Prefer C++ style comments in C++ sources.
222
223### Commenting out unused code
224Delete unused code instead of commenting it or using #define.
225
226### Indentation in sources [MANDATORY]
227Indentation in all sources should be set to two space characters.
228Use of tabulation characters for indentation is disallowed.
229
230### Separating spaces
231Punctuation rules follow the rules of English.
232C/C++ reserved words, commas, colons and semicolons should be followed by a space character if they are not at the end of line.
233There should be no space characters after '(' and before ')'. Closing and opening brackets should be separated by a space character.
234For better readability it is also recommended to surround conventional operators by a space character. See the following examples:
235
236~~~~~{.cpp}
237while (true) // NOT: while( true ) ...
238{
239 DoSomething (theA, theB, theC, theD); // NOT: DoSomething(theA,theB,theC,theD);
240}
241for (anIter = 0; anIter < 10; ++anIter) // NOT: for (anIter=0;anIter<10;++anIter){
242{
243 theA = (theB + theC) * theD; // NOT: theA=(theB+theC)*theD
244}
245~~~~~
246
247### Separate logical blocks
248Separate logical blocks of code with one blank line and comments.
249See the following example:
250
251~~~~~{.cpp}
252// check arguments
253Standard_Integer anArgsNb = argCount();
254if (anArgsNb < 3 || isSmthInvalid)
255{
256 return THE_ARG_INVALID;
257}
258
259// read and check header
260...
261...
262
263// do our job
264...
265...
266~~~~~
267
268Notice that multiple blank lines should be avoided.
269
270### Separate function bodies [MANDATORY]
271Use function descriptive blocks to separate function bodies from each other.
272Each descriptive block should contain at least a function name and description of purpose.
273See the following example:
274
275~~~~~{.cpp}
276// ----------------------------------------------
277// function : TellMeSmthGood
278// purpose : Gives me good news
279// ----------------------------------------------
280void TellMeSmthGood()
281{
282 ...
283}
284
285// ----------------------------------------------
286// function : TellMeSmthBad
287// purpose : Gives me bad news
288// ----------------------------------------------
289void TellMeSmthBad()
290{
291 ...
292}
293~~~~~
294
295### Block layout [MANDATORY]
296Figure brackets '{', '}' and each operator (for, if, else, try, catch) should be on dedicated line.
297General block should have layout similarly to the following:
298
299~~~~~{.cpp}
300while (expression)
301{
302 ...
303}
304~~~~~
305
306Entering block increases and leaving block decreases indentation to one tabulation.
307
308### Single-line operators
309Single-line conditional operator (if, while, for etc.) can be written without brackets on the following line.
310
311~~~~~{.cpp}
312if (!myIsInit) return Standard_False; // bad
313
314if (thePtr == NULL) // OK
315 return Standard_False;
316
317if (!theAlgo.IsNull()) // preferred
318{
319 DoSomething();
320}
321~~~~~
322
323Code on the same line is less convenient for debugging.
324
325### Use alignment
326Use alignment wherever it enhances readability. See the following example:
327
328~~~~~{.cpp}
329MyPackage_MyClass anObject;
330Standard_Real aMinimum = 0.0;
331Standard_Integer aVal = theVal;
332switch (aVal)
333{
334 case 0: computeSomething(); break;
335 case 12: computeSomethingElse (aMinimum); break;
336 case 3:
337 default: computeSomethingElseYet(); break;
338}
339~~~~~
340
341### Indentation of comments
342Comments should be indented similar to the code which they refer to or can be on the same line if they are short.
343Text should be delimited with single space character from slash.
344See the following example:
345
346~~~~~{.cpp}
347while (expression) //bad comment
348{
349 // this is a long multi-line comment
350 // which is really required
351 DoSomething(); // maybe, enough
352 DoSomethingMore(); // again
353}
354~~~~~
355
356### Early return statement
357Prefer early return condition rather than collecting indentations.
358Better write like this:
359
360~~~~~{.cpp}
361Standard_Integer ComputeSumm (const Standard_Integer* theArray,
362 const Standard_Size theSize)
363{
364 Standard_Integer aSumm = 0;
365 if (theArray == NULL || theSize == 0)
366 {
367 return 0;
368 }
369
370 ... computing summ ...
371 return aSumm;
372}
373~~~~~
374
375rather than:
376
377~~~~~{.cpp}
378Standard_Integer ComputeSumm (const Standard_Integer* theArray,
379 const Standard_Size theSize)
380{
381 Standard_Integer aSumm = 0;
382 if (theArray != NULL && theSize != 0)
383 {
384 ... computing summ ...
385 }
386 return aSumm;
387}
388~~~~~
389
390to improve readability and reduce unnecessary indentation depth.
391
392### Trailing spaces
393Trailing spaces should be removed when possible.
394Spaces at end of line are useless and do not affect functionality.
395
396### Headers order
397Split into groups: system headers, per framework headers, project headers; sort includes list alphabetically.
398This rule can improve readability, allows detection of useless header's multiple inclusions and makes 3rd-party dependencies clearly visible.
399
400~~~~~{.cpp}
401// system headers
402#include <iostream>
403#include <windows.h>
404
405// Qt headers
406#include <QDataStream>
407#include <QString>
408
409// OCCT headers
410#include <gp_Pnt.hxx>
411#include <gp_Vec.hxx>
412#include <NCollection_List.hxx>
413~~~~~
414
415@section OCCT_RULES_SECTION_4 Documentation rules
416
417The source code is one of the most important references for documentation.
418The comments in the source code should be complete enough to allow understanding of that code, and to serve as basis for other documents.
419The main reasons why comments are regarded as documentation and should be maintained are:
420
421- The comments are easy to reach - they are always together with source code
422- It's easy to update description in the comment when source is modified
423- The source itself represents a good context to describe various details that would require much more explanations in separate document
424- As a summary, this is the most cost-effective documentation
425
426The comments should be compatible with Doxygen tool for automatic documentation generation (thus should use compatible tags).
427
428### Documenting classes [MANDATORY]
429Each class should be documented in its header file (.hxx or .cdl).
430The comment should give enough details for the reader to understand the purpose of the class and main way of work with it.
431
432### Documenting class methods [MANDATORY]
433Each class or package method should be documented in the header file (.hxx or .cdl).
434The comment should explain the purpose of the method, its parameters, and returned value(s).
435Accepted style is:
436
437@verbatim
438//! Method computes the square value.
439//! @param theValue the input value
440//! @return squared value
441Standard_Export Standard_Real Square (Standard_Real theValue);
442@endverbatim
443
444### Documenting C/C++ sources
445It is very desirable to put comments in the C/C++ sources of the package/class.
446They should be detailed enough to allow any person to understand what does each part of code, and get familiar with it.
447It is recommended to comment all static functions (like methods in headers), and at least each 10-100 lines of the function bodies.
448There are also some rules that define how comments should be formatted, see section "Formatting Rules".
449Following these rules is important for good comprehension of the comments;
450moreover it makes possible to automatically generate user-oriented documentation directly from commented sources.
451
452@section OCCT_RULES_SECTION_5 Application design
453
454The following set of rules defines the common style which should be applied by any developer contributing to the open source.
455
456### Allow for possible inheritance
457Try to design general classes (objects) keeping possible inheritance in mind.
458This rule means that making possible extensions of your class the user should not encounter with problems of private implementations.
459Try to use protected members and virtual methods wherever you expect extensions in the future.
460
461### Avoid friend declarations
462Avoid using 'friend' classes or functions except some specific cases (ex., iteration) 'Friend' declarations increase coupling.
463
464### Set/get methods
465Avoid providing set/get methods for all fields of the class.
466Intensive set/get functions break down encapsulation.
467
468### Hiding virtual functions [MANDATORY]
469Avoid hiding a base class virtual function by a redefined function with a different signature.
470Most of the compilers issue warning on this.
471
472### Avoid mixing error reporting strategies
473Try not to mix different error indication/handling strategies (exceptions or returned values) on the same level of an application.
474
475### Minimize compiler warnings [MANDATORY]
476When compiling the source pay attention to and try to minimize compiler warnings.
477
478### Avoid unnecessary inclusion
479Try to minimize compilation dependencies by removing unnecessary inclusion.
480
481@section OCCT_RULES_SECTION_6 General C/C++ rules
482
483This section defines rules for writing portable and maintainable C/C++ source code.
484
485### Wrapping of global variables [MANDATORY]
486Use package or class methods returning reference to wrap global variables to reduces possible name space conflicts.
487
488### Avoid private members
489Use 'protected' members instead of 'private' wherever reasonable to enable future extensions.
490Use 'private' fields if future extensions should be disabled.
491
492### Constants and inlines over defines [MANDATORY]
493Use constant variables (const) and inline functions instead of defines (#define).
494
495### Avoid explicit numerical values [MANDATORY]
496Avoid usage of explicit numeric values. Use named constants and enumerations instead.
497Magic numbers are badly to read and maintain.
498
499### Three mandatory methods
500A class with any of (destructor, assignment operator, copy constructor) usually needs all of them.
501
502### Virtual destructor
503A class with virtual function(s) ought to have a virtual destructor.
504
505### Default parameter value
506Do not redefine a default parameter value in an inherited function.
507
508### Use const modifier
509Use const modifier wherever possible (functions parameters, return values etc.)
510
511### Usage of goto [MANDATORY]
512Avoid goto statement except the cases where it is really needed.
513
514### Declaring variable in for() header
515Declaring cycle variable in the header of the for() statement if not used out of cycle.
516
517~~~~~{.cpp}
518Standard_Real aMinDist = Precision::Infinite();
519for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter (theSequence);
520 aPntIter.More(); aPntIter.Next())
521{
522 aMinDist = Min (aMinDist, theOrigin.Distance (aPntIter.Value()));
523}
524~~~~~
525
526### Condition statements within zero
527Avoid usage of C-style comparison for non-boolean variables:
528
529~~~~~{.cpp}
530void Function (Standard_Integer theValue,
531 Standard_Real* thePointer)
532{
533 if (!theValue) // bad style - ambiguous logic
534 {
535 DoSome();
536 }
537
538 if (theValue == 0) // OK
539 {
540 DoSome();
541 }
542
543 if (thePointer != NULL) // OK, predefined NULL makes pointer comparison cleaner to reader
544 { // (nullptr should be used instead as soon as C++11 will be available)
545 DoSome2();
546 }
547}
548~~~~~
549
550@section OCCT_RULES_SECTION_7 Portability issues
551
552This chapter contains rules that are critical for cross-platform portability.
553
554### Ensure code portability [MANDATORY]
555It is required that source code must be portable to all platforms listed in the official 'Technical Requirements'.
556The term 'portable' here means 'able to be built from source'.
557
558The C++ source code should meet C++03 standard.
559Any usage of compiler-specific features or further language versions (C++11, until all major compliers on all supported platforms do not implement all it features)
560should be optional (escaped with appropriate preprocessor checks) and non-exclusive (alternative implementation should be provided, compatible with other compilers).
561
562### Avoid usage of global variables [MANDATORY]
563Avoid usage of global variables. Usage of global variables may cause problems of accessing them from another shared library.
564Instead of global variables, use global (package or class) functions that return reference to static variable local to this function.
565Another possible problem is the order of initialization of global variables defined in various libraries that may differ depending on platform, compiler and environment.
566
567### Avoid explicit basic types
568Avoid explicit usage of basic types (int, float, double etc.), use Open CASCADE Technology types (from package Standard - see Standard_Integer, Standard_Real, Standard_ShortReal, Standard_Boolean, Standard_CString and others) or specific typedef instead.
569
570### Use sizeof() to calculate sizes [MANDATORY]
571Do not assume sizes of types. Use sizeof() instead to calculate sizes.
572
573### Empty line at end of file [MANDATORY]
574In accordance with C++03 standard source files should be trailed by empty line.
575It is recommended to follow this rule for any plain text files for consistency and for correct work of git difference tools.
576
577@section OCCT_RULES_SECTION_8 Stability issues
578
579The rules listed in this chapter are important for stability of the programs that use Open CASCADE Technology libraries.
580
581### OSD::SetSignal() to catch exceptions
582When using Open CASCADE Technology in an application, make sure to call OSD::SetSignal() function when the application is initialized.
583This will install C handlers for run-time interrupt signals and exceptions,
584so that low-level exceptions (such as access violation, division by zero etc.) will be redirected to C++ exceptions
585(that use try {...} catch (Standard_Failure) {...} blocks).
586The above rule is especially important for robustness of modeling algorithms.
587
588### Cross-referenced handles
589Take care about cycling of handled references to avoid chains which will never be freed.
590For that purpose, use a pointer at one (subordinate) side. See the following example:
591
592In MyPackage.cdl:
593
594 class MyFirstHandle;
595 class MySecondHandle;
596 pointer MySecondPointer to MySecondHandle;
597 ...
598
599In MyPackage_MyFirstHandle.cdl:
600
601 class MyFirstHandle from MyPackage
602 ...
603 is
604 ...
605 SetSecondHandleA (me: mutable; theSecond: MySecondHandle from MyPackage);
606 SetSecondHandleB (me: mutable; theSecond: MySecondHandle from MyPackage);
607 ...
608 fields
609 ...
610 mySecondHandle : MySecondHandle from MyPackage;
611 mySecondPointer : MySecondPointer from MyPackage;
612 ...
613 end MyFirstHandle from MyPackage;
614
615In MyPackage_MySecondHandle.cdl:
616
617 class MySecondHandle from MyPackage
618 ...
619 is
620 ...
621 SetFirstHandle (me: mutable; theFirst: MyFirstHandle from MyPackage);
622 ...
623 fields
624 ...
625 myFirstHandle : MyFirstHandle from MyPackage;
626 ...
627 end MySecondHandle from MyPackage;
628
629In C++ code:
630
631~~~~~{.cpp}
632void MyFunction()
633{
634 Handle(MyPackage_MyFirstHandle) anObj1 = new MyPackage_MyFirstHandle();
635 Handle(MyPackage_MySecondHandle) anObj2 = new MyPackage_MySecondHandle();
636 Handle(MyPackage_MySecondHandle) anObj3 = new MyPackage_MySecondHandle();
637
638 anObj1->SetSecondHandleA(anObj2);
639 anObj1->SetSecondHandleB(anObj3);
640 anObj2->SetFirstHandle(anObj1);
641 anObj3->SetFirstHandle(anObj1);
642
643 // memory is not freed here !!!
644 anObj1.Nullify();
645 anObj2.Nullify();
646
647 // memory is freed here
648 anObj3.Nullify();
649}
650~~~~~
651
652### C++ memory allocation
653In C++ use new and delete operators instead of malloc() and free().
654Try not to mix different memory allocation techniques.
655
656### Match new and delete [MANDATORY]
657Use the same form of new and delete.
658
659~~~~~{.cpp}
660aPtr1 = new TypeA[n]; ... ; delete[] aPtr1;
661aPtr2 = new TypeB(); ... ; delete aPtr2;
662aPtr3 = Standard::Allocate (4096); ... ; Standard::Free (aPtr3);
663~~~~~
664
665### Methods managing dynamical allocation [MANDATORY]
666Define a destructor, a copy constructor and an assignment operator for classes with dynamically allocated memory.
667
668### Uninitialized variables [MANDATORY]
669Every variable should be initialized.
670
671~~~~~{.cpp}
672Standard_Integer aTmpVar1; // bad
673Standard_Integer aTmpVar2 = 0; // OK
674~~~~~
675
676Uninitialized variables might be kept only within performance-sensitive code blocks and only when their initialization is *guarantied* by following code.
677
678### Do not hide global new
679Avoid hiding the global new operator.
680
681### Assignment operator
682In operator=() assign to all data members and check for assignment to self.
683
684### Float comparison
685Don't check floats for equality or non-equality; check for GT, GE, LT or LE.
686
687~~~~~{.cpp}
688if (Abs (theFloat1 - theFloat2) < theTolerance)
689{
690 DoSome();
691}
692~~~~~
693
694Package 'Precision' provides standard values for SI units and widely adopted by existing modeling algorithms:
695- Precision::Confusion() for lengths in meters
696- Precision::Angular() for angles in radians
697
698as well as definition of infinity values within sanity range of double precision:
699- Precision::Infinite()
700- Precision::IsInfinite()
701- Precision::IsPositiveInfinite()
702- Precision::IsNegativeInfinite()
703
704### Non-indexed iteration
705Avoid usage of iteration over non-indexed collections of objects.
706If such iteration is used, make sure that the result of the algorithm does not depend on order.
707
708Since the order of iteration is unpredictable in this case, it frequently leads to different behavior of the application from one run to another,
709thus embarrassing the debugging process.
710It mostly concerns mapped objects for which pointers are involved in calculating the hash function.
711For example, the hash function of TopoDS_Shape involves the address of TopoDS_TShape object.
712Thus the order of the same shape in the TopTools_MapOfShape will vary in different sessions of the application.
713
714### Do not throw in destructors
715Do not throw from within destructor.
716
717### Assigning to reference [MANDATORY]
718Avoid possible assignments of the temporary object to a reference.
719Different behavior for different compiler of different platforms.
720
721@section OCCT_RULES_SECTION_9 Performance issues
722
723These rules define the ways of avoiding possible loss of performance caused by ineffective programming.
724
725### Class fields alignment
726In a class, declare its fields in the decreasing order of their size for better alignment.
727Generally, try to reduce misaligned accesses since they impact the performance (for example, on Intel machines).
728
729### Fields initialization order [MANDATORY]
730List class data members in the constructor's initialization list in the order they are declared.
731
732~~~~~{.cpp}
733class MyPackage_MyClass
734{
735
736public:
737
738 MyPackage_MyClass()
739 : myPropertyA (1),
740 myPropertyB (2) {}
741
742// NOT
743// : myPropertyB (2),
744// myPropertyA (1) {}
745
746private:
747
748 Standard_Integer myPropertyA;
749 Standard_Integer myPropertyB;
750
751};
752~~~~~
753
754### Initialization over assignment
755In class constructors prefer initialization over assignment.
756
757~~~~~{.cpp}
758MyPackage_MyClass()
759: myPropertyA (1) // preferred
760{
761 myPropertyB = 2; // not recommended
762}
763~~~~~
764
765### Optimize caching
766When programming procedures with extensive memory access, try to optimize them in terms of cache behavior.
767Here is an example of how cache behavior can be impact:
768On x86 this code
769
770~~~~~{.cpp}
771Standard_Real anArray[4096][2];
772for (Standard_Integer anIter = 0; anIter < 4096; ++anIter)
773{
774 anArray[anIter][0] = anArray[anIter][1];
775}
776~~~~~
777
778is more efficient than
779
780~~~~~{.cpp}
781Standard_Real anArray[2][4096];
782for (Standard_Integer anIter = 0; anIter < 4096; ++anIter)
783{
784 anArray[0][anIter] = anArray[1][anIter];
785}
786~~~~~
787
788since linear access (above) does not invalidate cache too often.
789
790@section OCCT_RULES_SECTION_10 Examples
791
792Here is C++ source file sample:
793
794@verbatim
795//! Sample documented class
796class Package_Class
797{
798
799public: //! @name public methods
800
801 //! Method computes the square value.
802 //! @param theValue the input value
803 //! @return squared value
804 Standard_Export Standard_Real Square (const Standard_Real theValue);
805
806private: //! @name private methods
807
808 //! Auxiliary method
809 void increment();
810
811private: //! @name private fields
812
813 Standard_Integer myCounter; //!< usage counter
814
815};
816@endverbatim
817
818~~~~~{.cpp}
819#include <Package_Class.hxx>
820
821// ==========================================================
822// function : Square
823// purpose : Method computes the square value
824// ==========================================================
825Standard_Real Package_Class::Square (const Standard_Real theValue)
826{
827 increment();
828 return theValue * theValue;
829}
830
831// ==========================================================
832// function : increment
833// purpose :
834// ==========================================================
835void Package_Class::increment()
836{
837 ++myCounter;
838}
839~~~~~
840
841TCL script for Draw Harness:
842~~~~~{.tcl}
843# show fragments (solids) in shading with different colors
844proc DisplayColored {theShape} {
845 set aSolids [uplevel #0 explode $theShape so]
846 set aColorIter 0
847 set THE_COLORS {red green blue1 magenta1 yellow cyan1 brown}
848 foreach aSolIter $aSolids {
849 uplevel #0 vdisplay $aSolIter
850 uplevel #0 vsetcolor $aSolIter [lindex $THE_COLORS [expr [incr aColorIter] % [llength $THE_COLORS]]]
851 uplevel #0 vsetdispmode $aSolIter 1
852 uplevel #0 vsetmaterial $aSolIter plastic
853 uplevel #0 vsettransparency $aSolIter 0.5
854 }
855}
856
857# load modules
858pload MODELING VISUALIZATION
859
860# create boxes
861box bc 0 0 0 1 1 1
862box br 1 0 0 1 1 2
863compound bc br c
864
865# show fragments (solids) in shading with different colors
866vinit View1
867vclear
868vaxo
869vzbufftrihedron
870DisplayColored c
871vfit
872vdump $imagedir/${casename}.png 512 512
873~~~~~
874
875GLSL program:
876~~~~~{.fs}
877vec3 Ambient; //!< Ambient contribution of light sources
878vec3 Diffuse; //!< Diffuse contribution of light sources
879vec3 Specular; //!< Specular contribution of light sources
880
881//! Computes illumination from light sources
882vec4 ComputeLighting (in vec3 theNormal,
883 in vec3 theView,
884 in vec4 thePoint)
885{
886 // clear the light intensity accumulators
887 Ambient = occLightAmbient.rgb;
888 Diffuse = vec3 (0.0);
889 Specular = vec3 (0.0);
890 vec3 aPoint = thePoint.xyz / thePoint.w;
891 for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
892 {
893 int aType = occLight_Type (anIndex);
894 if (aType == OccLightType_Direct)
895 {
896 directionalLight (anIndex, theNormal, theView);
897 }
898 else if (aType == OccLightType_Point)
899 {
900 pointLight (anIndex, theNormal, theView, aPoint);
901 }
902 }
903
904 return vec4 (Ambient, 1.0) * occFrontMaterial_Ambient()
905 + vec4 (Diffuse, 1.0) * occFrontMaterial_Diffuse()
906 + vec4 (Specular, 1.0) * occFrontMaterial_Specular();
907}
908
909//! Entry point to the Fragment Shader
910void main()
911{
912 gl_FragColor = computeLighting (normalize (Normal),
913 normalize (View),
914 Position);
915}
916~~~~~