Coding standards
Craig Southeren
Last updated 7 July 2007

Introduction

PWLib and OPAL/OpenH323 have been written using a consistent coding style that has been developed over the last ten years. This makes the code easier to read and debug, and helps to avoid some of the problems that can occur when programming in C++. 

Filenames

Source files have the suffix .cxx and header files have the suffix .h. It's just the way the we have always done it.

Identifier names

Identifiers are composed by concatenating words with leading capitals on each word. Use of highly abbreviated identifiers is discouraged - it's not like you have to pay for each extra character used.

Types, classes and functions all have a leading upper case character (e.g. TestClassName), whereas variables have a leading lower case character (e.g. thisIsAVariable). There is a growing tendency to prefix class member variables with "m_", but full Hungarian notation is not required.

All classes exported from PWLib have a "P" prefix to avoid namespace collisions.

The code generated by the ASN parser prefixes all member fields with "m_" and all emumeration values with "e_". 

Remove all compiler warnings 

Most modern compilers report warnings at compile time for a good reason - they usually point out real or potential problems in the code. Sometimes, an important warning can hide inside a list of benign warnings - so all warnings should be removed to avoid developers becoming "desensitised".

Indenting 

If, for and switch statements are indented two spaces per level. 

Most importantly - never use tabs. Always use spaces. 

Open braces go on the trailing edge of lines unless they are the opening brace of a class definition of function. 

Correct Not correct Definitely not correct
class Class
{
  public:
    int Function(int arg);
};

int Class::Function(int arg)
{
  if (arg != 0) {
    switch(arg) {
      case 1:
        cout << arg;
        break;
      default:
        break;
    }

class Class {
  public:
    int Function(int arg);
};

int Class::Function(int arg) {
if (arg != 0) 
{
  switch(arg) 
  {
    case 1:
      cout << arg;
      break;
    default:
      break;
  }
}

class Class { public: int Function(int arg);
};

int Class::Function(int arg){
if (arg != 0) {
 switch(arg) {
 case 1:
 cout << arg;
 break;
 default:
 break;
 }
}

Declare locals near use

C++ allows variables to be declared anywhere in a block of code. This comes as a great shock to C programmers who are used to declaring everything at the top of a code block. This can greatly increase the readability of code and can avoid having to search backwards several pages to find a variable declaration.

Don't use global unless absolutely necessary

There should be very few places where you need a global. If you think it is needed, use a singleton class instead

Initialise member variables in the constructor using the initialisation list

Where possible, initialise member variables as part of the constructor initialisation. Also note that some compilers (gcc) will complain if member variables are not initialised in the same order they are declared.

Always use reference parameters to functions

A C++ reference is just a pointer with attitude, so always pass function parameters by reference rather than value, like so:

Correct Not correct
void MyFunction(const PString & str)
{
  cout << "The string is " << str << endl;
void MyFunction(PString str)
{
  cout << "The string is " << str << endl;
}

Passing by const reference will have exactly the same effect as passing by value, but without associated memory and speed overhead of copying the object, and should be used in all cases unless the function needs to change the value of the argument.

Change History

10 July 2007 Craig Southeren Initial version finished
1 June 2004 Craig Southeren Initial version started

Copyright © 2003-2007 by Post Increment A.B.N 95 856 785 279
All Rights Reserved
All trademarks and copyrights on this page are owned by their respective owners.