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 nearly 10 years and had 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.
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 see in large boolean statements of an
if
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
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.
Write each parent class in one line.
Example:
class MyChildClass : public ParentClass1, private ParentClass2B< this you gain also an fast overview over the inherited classes.
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 |
// 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.
for good documentation use a header similar to the following one:
/** ** [functionname] ** ** [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] ** ** [description of the purpose of the function] ** ** [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 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.
Use #if 0 ... #endif
for code you want to deactivate. Always comment, why you have deactivated this particular code.
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
Try to use the modifier const
wherever intended and possible, by this you avoid to change pointers and
class members without intention.
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.
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.
Define 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.
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.
iosfwd
or make an own forward declaration.
using
before an include.
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.
delete
operator, otherwise
you gain undefined behaviour if calling them for an vector of elements.
try/catch
statement. If you use one always catch the specialized exceptions before the more common ones. Especially catch only exception which you can handle.
try/catch
statement in main
or a mainloop an exception which reaches this level is nearly every time a programming error, which should cause a program abort.
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.