wiki:CodingGuidelines

Version 13 (modified by FrederikHeber, 13 years ago) ( diff )

Added section on using the logger


  1. Coding Style
    1. How MoleCuilder code should look like
    2. One class, one file
  2. Coding hints
    1. Some hints on good code vs. bad code
      1. end of stream checking
      2. Use of new/delete, return
      3. Use of return
      4. Specific (initial) values of variables
      5. Make use of declaring member variables and functions const
      6. Use forward declarations
      7. Use boost libraries
      8. Use the logger, not cout/cerr


Coding Style

How MoleCuilder code should look like

Below you find a brief but hopefully complete list on how the code of espack should look like:

  • identate by two spaces, never tabs
  • Code Style from Eclipse, see ESPACK_codestyle.xml:
    /*
     * A sample source file for the code formatter preview
     */
    #include <math.h>
    
    class Point
    {
    public:
      Point(double xc, double yc) :
        x(xc), y(yc)
      {
      }
      double distance(const Point& other) const;
    
      double x;
      double y;
    };
    
    double Point::distance(const Point& other) const
    {
      double dx = x - other.x;
      double dy = y - other.y;
      return sqrt(dx * dx + dy * dy);
    }
    

One class, one file

Always have just one class implementation per file!. This allows for compiling the implementations in parallel and it is natural to split up the implementation with respect to the class structure. The same holds for the declaration in the header file.

Coding hints

Some hints on good code vs. bad code

end of stream checking

Using

   std::inputstream in;
   while (!in.eof()) {
     ..
   }

is bad. Rather one should use

   std::inputstream in;
   while (in.getline(...)) {
     ..
   }

or

   std::inputstream in;
   for(int j; in >> j;;) {
     ..
   }

or

   std::inputstream in;
   in >> j;
   if (in.fail())
    ..

This involves some extra typing but ensures that in case of faulty streams the error is properly pointed at.

Use of new/delete, return

The new and delete statements are written without brackets, they are not functions, i.e.

  new pointer;
  new array[3];
  delete pointer;
  delete[] array;

Use of return

The return statements should look like this

 return bar;
 return (foo && bar);

and not like

 return (bar);
 return(foo);

Specific (initial) values of variables

In general all variables always have to be initialized (we don't care about the extra tic, even if operating system guarantees zero as default memory value).

If they have to be set to some very small or very big value, use std::numeric_limits

  double smalldouble = std::numeric_limits<double>::min();
  double largedouble = std::numeric_limits<double>::max();

Also remember that there are also ::infinity() and alikes to set an illegal value which can be checked.

Make use of declaring member variables and functions const

We want to have a clean interface. Hence, it is vital to state in the interface that a function does not change the internal state of a class instance. If so, make it const.

The same holds for variables. If they are set in the constructor and only read afterwards, make them const.

Note: const variables are tricky with serialization, but in this specific case it is allowed to use const_cast<>() to allow writing a const member variable outside the constructor.

Note: If a function is const in nature but modifies a very specific variable (specific to the function but needs to be contained in the class scope, e.g. a counter how often the function has been called), make it mutable_.

Use forward declarations

Whenever possible use forward declarations in header files. They are vital in reducing compilation times. Remember that the preprocessor first compiles every include into the file subsequently served to the compiler. The larger this file becomes, the longer compilation takes.

If a function defined in a header file just has the parameter as a reference or as pointer, don't add the include but only the forward declaration in the header file.

// some header file

class MightyClass;

class SmallClass {
  ...
  void foo(MightyClass &_m);
  ...
};

Use boost libraries

Although in general, we do not want to rely to heavily on other libraries (because of licenses), do not reimplement the wheel if what you need is found in STL or boost which both are (quasi) standards.

Use the logger, not cout/cerr

Don't use std::cout or std::cerr (except maybe for internal tests which never make it into a commit).

Always use

#include "CodePatterns/Log.hpp"

  ...
  LOG(1, "INFO: Variable bla contains " << bla << ".");
  ...
  ELOG(1, "Variable is " << bla << " which is invalid!");
  ...

This way we can control the verbosity of the code easily and we do not end up with many commented-out wasteland alike ... std::cout << "Variable bla is " << ....

Attachments (1)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.