2. Code Convention
The set of rules listed here are the only 'imposed' rules which have been adopted for the development of Geant4. We think they might become useful also for those users who will develope C++ code for applications related to Geant4 and, why not?, in general !
As an object-oriented toolkit, Geant4 can be certainly extended and refined by physicists and experts all over the world, who may have used or will use their own coding conventions and rules, different from each others. It is and has been then important not to impose too fixed rules or style-conventions for a world-wide collaboration like GEANT4, but just flexible and adequate guidelines for programming and coding styles.
"C++ was designed to support data abstraction and object-oriented programming in addition to traditional C programming techniques. It was not meant to force any particular programming style upon all users" (B.Stroustrup).
If a class does not have a constructor there is no guarantee of how objects of that class will be initialized, whilst data members should be explicitly initialized therein. When the constructor dynamically allocates memory, a destructor must be added to return the memory to the free pool when an object gets cleaned up.
The assignment operator is called when one instance of a class is assigned to another. The copy constructor defines the behaviour of the class when it is passed by value as an argument, returned by value from a function, or used to initialize one instance with the value of another class instance. Defining this constructor, all the class objects are copied properly. When it doesn't make sense to copy or assign instances of a given class, the copy constructor or the = operator should be made private.
Inline expansion avoids the overhead of a function call and can result in large savings of CPU time expecially if applied to member functions supporting public access to private data (allowing the maximum data-hiding for a required performance).
To garantee the encapsulation of a base class is always preferable to use protected data over friends or public data and then use inheritance.
Especially from const* or const, type casting may be dangerous for data-hiding. In addition pointers should not be cast to int for portability reasons.
For portability and maintainability reasons. The use of costants (const) is a valid solution.
For the basic numeric types (int, float, double, etc ...), different compilers and different platforms provide different value ranges. In order to assure portability, the use of G4int, G4float, G4double, which are base classes globally defined is preferable. G4 types implement the right generic type for a given architecture.
Possibly avoid the use of underscore "_" characters within variables or function names (ex. theTotalEnergy, SetEnergyTable(), GetTrackPosition(), ...).
(ex. G4Material, G4GeometryManager, G4ProcessVector, ...) to keep an homogeneous naming style for GEANT4 specific classes.
For maintainability reasons and to make easier retrieval of classes' definitions across each category.
For maintainability reasons and to make easier retrieval of classes' implementations across each category.
In order to avoid multiple declarations and circular dependences in the code. Ex.:
#ifndef NAME_HH #define NAME_HH ... #endif
All files should begin with:
// $Id: codeConvention.html,v 1.2 1998/12/02 03:50:59 amako Exp $
and a half line comment with the name of the original author,
update notes and dates. The $Id: codeConvention.html,v 1.2 1998/12/02 03:50:59 amako Exp $ will expand to filename
and last updater in CVS.
Bugs related to this problem are extremely difficult to track down !
In particular, remember to delete items of a pointer based collection which were allocated on the heap.
Define inlined functions in the .icc file and check that the compiler is effectively inlining them (using the proper compiler options).
Check if allocation was done already.
As of Tools.h++ V7.0.1:
operator() fetches an element and does no bounds
checking of the index.
operator[] fetches an element and does bounds check.
The library is only aware of insertions by insert()
(and related functions).
Therefore:
use the declaration int main() instead of void main() or main() (this "implicite int" will be excluded from the C++ standard soon).
Items stored in pointer collections e.g. RWTPtrOrderedVector can be deleted by the method clearAndDestroy().
It is best to make the corresponding member functions private.
Methods with multiple return points cannot be inlined and some compilers (e.g. HP-CC) complain about this.
Look inside those files in CLHEP/Units before defining local constants or putting hard-coded numbers in the code.