2. Code Convention

"A major benefit of object-oriented programming languages like C++ is the degree of reuse that can be achieved in well-engineered systems. A high degree of reuse means that far less code must be written for each new application; consequently, that is far less code to maintain." (G.Booch).

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 !

## 2.1 Introduction

Geant4 as object-oriented toolkit is thought to be an integration of components (sets of classes) which are specific to the HEP applications or part of general foundation class libraries, math libraries (commercial or free) already implemented and distributed world-wide, useful as building blocks for a wide variety of applications. Even within HEP, the reusability of object-oriented software across different laboratories and between different experiments will be essential.

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).

## 2.2 Programming guidelines

The programming guidelines are the ones which refer to the way of using the features of the programming languages. They have to do with things like the adhesion to the object oriented paradigm (data-hiding, encapsulation, etc ...), the performance and portability.

- Every class should have at least one constructor and a destructor even if it does nothing or is defined to do nothing.

  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.

- Each class should have an assignment operator:
  `ClassName& operator=(const ClassName&)`
  and a copy constructor:
  `ClassName(const ClassName&)`
  when allocating subsidiary data structures on the heap or consume any other kind of shared resources.

  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.

- Data members should be made private/protected and accessed by inline functions in order to best implement information-hiding.

  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).

- The use of global variables or functions should be avoided where possible, in order to respect encapsulation.

- The use of friend classes should be avoided where possible.

  To garantee the encapsulation of a base class is always preferable to use protected data over friends or public data and then use inheritance.

- The use of type casting should be avoided.

  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.

- Hard-coded numbers within the code must be avoided.

  For portability and maintainability reasons. The use of costants (`const`) is a valid solution.

- Instead of the raw C types, the G4 types should be used.

  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.

## 2.3 Coding-style conventions

The coding-style guidelines are the ones which refer to the editing styles of the source code. They have to do with things like the code maintainability and readability.

- The public, protected and private keywords must be used explicitly in the class declaration in order to make easier code readability.

- English and self-explaining names for constants, variables and functions should be used for code readability.

  Possibly avoid the use of underscore "_" characters within variables or function names (ex. `theTotalEnergy, SetEnergyTable(), GetTrackPosition()`, ...).

- The code must be properly indented (ex. 2 characters indentation when inside a control structure) for readability reasons.

- Each GEANT4 class name should begin with G4

  (ex. `G4Material, G4GeometryManager, G4ProcessVector`, ...) to keep an homogeneous naming style for GEANT4 specific classes.

- Each header file should contain only one or related class declarations.

  For maintainability reasons and to make easier retrieval of classes' definitions across each category.

- Each class implementation source code should go into a single source file.

  For maintainability reasons and to make easier retrieval of classes' implementations across each category.

- Each header file must be protected from multiple inclusions.

  In order to avoid multiple declarations and circular dependences in the code. Ex.:

          #ifndef NAME_HH
          #define NAME_HH
          ...
          #endif

- Each file should contain a short header about the author, updates (CVS) and date.

  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.

## 2.4 Coding-style for writing a Geant4 application

Style to adopt to write a Geant4 main application.

## 2.5 Programming Suggestions learned from experience

Here is a list of rules/hints which we could collect after all periodical sessions of QA/QC on the developed code. These "hints" have been made public to Geant4 developers in order to avoid the most common mistakes and improve the quality of the code.

- Initialize all data members of a class in each constructor (pointers, `G4ints`, etc.)

  Bugs related to this problem are extremely difficult to track down !

- Do not insert items allocated on the heap into value-based collections (Or, at least, preserve the pointer for deletion)

- Properly destruct objects

  In particular, remember to delete items of a pointer based collection which were allocated on the heap.

- Inline short and frequently used member functions

  Define inlined functions in the .icc file and check that the compiler is effectively inlining them (using the proper compiler options).

- A member function doing allocations on the heap may leak memory if the user invokes the function several times

  Check if allocation was done already.

- Access of elements of the RWTPtrOrderedVector collections

  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:

  - filling the array by insert() and reading it with [] works;
  - filling the array by () and reading it by () works;
  - filling by [] does NOT work any more.

- The return type of function main()

  use the declaration int `main()` instead of `void main()` or `main()` (this "implicite int" will be excluded from the C++ standard soon).

- Programs should return:
  - 0 or `EXIT_SUCCESS` on success;
  - nonzero or `EXIT_FAILURE` on error.

- Deletion of elements in pointer based collections

  Items stored in pointer collections e.g. `RWTPtrOrderedVector` can be deleted by the method `clearAndDestroy()`.

- Problems with classes that cannot be copied/assigned to/constructed etc.

  It is best to make the corresponding member functions private.

- Use const declarations whenever possible instead of numbers in the code

- Avoid multiple return points in a method where possible

  Methods with multiple return points cannot be inlined and some compilers (e.g. HP-CC) complain about this.

- Use G4Exception to print an error message and exit the program

- Use costants and units defined in `PhysicalConstants.h` and `SystemOfUnits.h`

  Look inside those files in CLHEP/Units before defining local constants or putting hard-coded numbers in the code.

- Do not code bit-wise operations within a word. Consider a word as atomic!