Borg's Coding Guideline


Why?

The main reason, why a programmer should keep to a coding guideline, is

This is especially useful for maintenance of code. So any programmer can understand the code much faster, even then when it is his own code, which he has written some time ago.

Especially in larger teams there is always the need, that other team members have to touch code which somebody else in the team has written. In this case a coding guideline guarantees that code will keep readable and easy to understand even if lots of programmers are working together at some piece of it.

But be not mistaken a coding guideline is just that a guideline and not a natural law. So just take the following chapters as a good advice of somebody, who has now programmed for a long time by now and has learned the use of a good guideline the hard way.

Most of the following text can be a guideline for nearly every programming language, especially object oriented. But some points take care of special C and C++ features.


Code Format

white spaces

I suggest for an easy readable code the following conventions for the use of white spaces:

expressions

If an expressions spans more than one line you should write operators every time at right side.

Example:

 x =   a 
     * (   b 
         + c ); 
Especially keep, like in the example, the order of operators in mind. How useful this is you can easily be seen in large boolean statements of an if.

functions

A good way to declare a function is to write the return type in one line, in the next the function name and in the following lines the parameters of the function.

Example:

const int
MyFunc(
  int x,
  int y )
This gives you an fast overview over the information regarding the function and an easy way to seek for the definition because it's normally the only line that starts with the text MyFunc

class constructors

If you initialize members of a class, write each member in an own line.

Example:

MyClass::MyClass()
  : member1_( ... ),
    member2_( ... )
So you can easily compare with the class declaration, if you have initialized all members.

class inheritance

Write each parent class in one line.

Example:

class MyChildClass
  : public  ParentClass1,
    private ParentClass2  
By this you gain also an fast overview over the inherited classes.


Naming Conventions

common

element first letter other letters
namespace small letter small letters or numbers
types capital letter small or capital letters and numbers.
method, variable, parameter small letter small or capital letters and numbers.
classmembers small letter small or capital letters and numbers. last letter should be: _
constants capital letter capital letters and underlines
By this your code will be easier to read and to understand.


Comments

common

The meaning of the last point is:
don't comment the working of the code, but comment the effects, if not already understood by reading the code.
Bad style:
// initialize index with -1
int index = -1;
Better style:
// initialize index with the value for nothing found.
int index = -1;
Best style:
#define NOTHING_FOUND -1
...
int index = NOTHING_FOUND;
In the last case you don't need any comment, and every code which uses the macro is easy to read. In this example it may look like a bit of to much effort to gain a little advantage, but I think you have got the point.

function header

for good documentation use a header similar to the following one:

/**
 ** [functionname]
 **
 ** [description of the purpose of the function]
 **
 ** [a list of parameters with short description and sometimes allowed value range]
 ** 
 ** [a short description of every result this function may produce and the intent of
 **   errorcodes]
 **
 ** [maintenance responsibility for this function]
 **
 ** [date when the function was last changed]
 **
 **/
If you fill always all the fields above, when you write a function and keep them up to date after that. You will have nearly all informations you need to understand the function. Especially user of your modules will be thankful for the good documented interface.

If you use any language supported by doxygen (like C/C++, Java) I strongly recommend to use the doxygen comment format:

/**
 ** [functionname]
 **
 ** [description of the purpose of the function]
 **
 ** @param
 ** @param
 ** 
 ** @result
 **
 ** @author
 **
 ** @date
 **
 **/

code blocks

If you close a large code block always write a short comment, which refers to the start of the block.

Example:

if( x > 50 )
{
...
} // if ( x > 50 )
By this you will always get a good overview and especially you will always know the meaning of an else after a long code block in an if-statement.


Code Style

deactivating code

Use #if 0 ... #endif for code you want to deactivate. Always comment, why you have deactivated this particular code.

class constructors

Always keep the order of the definition of the members of a class, when initializing them before a constructor, because not the written order of the initialization list, but the order of definition determines, when which member will be initialized in C++.
Always initialize all members of a class. Nothing can have such unexpected side effects as an uninitialized variable.

private

Always keep nearly all members of your classes private with special access methods. So you can always guarantee that no invalid values are stored in your classes.

The private members and methods of a class should be always written at the end of this class to hide them as good as possible before the eyes of the user, who should not use or even know them.

Even in methods of a class with private members use the access methods for this members to avoid errors by directly changing values.

const

In C++ try to use the modifier const wherever intended and possible, by this you avoid to change pointers and class members without intention.

namespaces

In C++ use namespaces to get a file overlapping semantic structure and to make the code easier to read with meaningful prefixes (the namespace names).

Also you can avoid naming conflicts with standard functions and methods of the programming language, if you put your function in an own namespace.

For invoking own Methods of a class use the pointer this and for all global Methods the C++ prefix ::. by this you will never have to seek where a method belongs to.

references

Where possible use const& references. By this you can avoid a lot of common errors.

But do not use any references for the basis types like int. The only reason for this is if you need more than one return value.

locale variables

Define in C++ locale variables always with the smallest scope possible. This is especially useful to avoid the reuse of locale variables without intentions. Sometimes it's even good style to start a new scope with {...} just for the definition of one locale variable, especially if this variable is the abbreviation of a complex statement.

Initialize any locale variable immediately when you declare it.

simplicity

Keep the code as simple as possible. Prefer small classes, methods and files before large and complex ones. By this it is much easier to keep the overview and reuse parts of the code.


Header Includes


Exceptions

Exception are one way to propagate an error code out of functions without an return type, especially constructors. They allow you too, to propagate errors easily without information loose through more than one call layer. By this you can easily communicate errors between completely different parts of programs.

assert vs. exceptions

assert is meant for code where you have the full control, which refers to all data which belong to your module, class or function. For example to guarantee that a member of your class is in a given value area. For all values which are beyond your control, like parameters of functions or side effects, use exceptions. By this you always propagate the error to the point, where it was caused and that code has then the possibility to handle the problem correctly.





Startseite

Impressum