wiki:StyleGuide

AVANGO C++ Style Guide

Objectives

The goal of this guide is to provide standard rules for AVANGO C++ developers which help to maintain a uniform coding style. This not only supports easier understanding but should ideally help to produce less erroneous code. Unless there are good reasons you should really follow the rules written down in this document.

We start with a general overview over source code layout and naming issues before going into the details and providing a minimal template as a starting point for your AVANGO modules.

Overall Format

  • Add yourself to the AUTHORS file when you change something inside a module
  • Page width is 100 chars
  • Do not use tabs for indentation
  • Indentation width is 2 spaces
  • Every file starts with a copyright header which may only be preceded by a Mode line, e.g. -*- Mode:C++ -*- or a  Shebang, e.g. #!/bin/sh

Naming Guidelines

  • File names usually correspond to the contained class (e.g. Type.h)
  • Type names have the format: Word1Word2...
  • Function names have the format: word1Word2...();
  • Function arguments have the format: word1Word2...
  • AVANGO Fields have the format: (S|M)[A]FType Word1Word2...;
  • Other instance members have the format: mWord1Word2...
  • Static members have the format: sWord1Word2...
  • Global variables have the format: gWord1Word2...
  • Local variables and file static variables (variables in unnamed namespace) have the format word1_word2...
  • Constants are uppercase, words separated with underscores: WORD1_WORD2_...
  • Namespace naming Scheme: av for core library, av::moduleName for extension libraries (e.g. av::osg, av::osgParticle, av::tools)
  • Don't add redundant namespace information (e.g. to function parameters)
  • Include directories usually correspond to namespaces with av replaced with avango, i.e. core library headers go to $prefix/include/avango,  OpenSceneGraph extension headers to $prefix/include/avango/osg. More examples: $prefix/include/avango/osgParticle, $prefix/include/avango/tools

Coding Guidelines

  • Check arguments at beginning of functions and throw an exception if you can't recover
  • Check pointer arguments for validness
  • Use C++-style casts wherever possible. If you really have to use C-style casts, add a comment why
  • TRUE and FALSE are deprecated, use bool type wherever possible
  • NULL is deprecated, use 0 instead
  • Use typename instead of class for template arguments
  • Do not declare variables at beginning of the block, but as needed
  • Don't add unnecessary spaces inside brackets. Use this style:
    void f(int i);
    template <typename T> void g();
    std::set<int> s;
    
  • Initializer lists in Constructors have the following format:
    Class::Class() :
      mMember1(),
      mMember2(),
      ...
      mMemberN()
    {
      ...
    }
    
  • Within function blocks, follow this style for conditionals:
    if ()
    {
      ...
    }
    
    if ()
    {
      ...
    }
    else if ()
    {
      ...
    }
    
    switch ()
    {
      case1:
        break;
      default:
        break;
    }
    
  • In general, break brackets apart from declarations and command lines
    namespace av
    {
    
      class C
      {
        ...
      public:
        ...
      };
    
    }
    
    void f()
    {
      while (true)
      {
        doSomething();
      }
    }
    

Error Handling

Use assertions to validate internal assumptions. Use exception to announce wrong interface usage or to signal local error states to the user. Whenever possible try to use std exceptions.

Write Tests

Write self-contained tests for your modules using the AVANGO UnitTest++ infrastructure. Link the tests against the final library instead of the separate convenience libraries (e.g. don't use libfields.la but libavango.la). This way we don't run into trouble when new dependencies are introduced.

Documentation Guidelines

  • Document at least the public and protected interface using Doxygen comments in Javadoc style (see References below).
  • Document arguments when there meaning is not obvious.
  • Document exceptions functions may throw.
  • Define groups for your extension library and document your extensions library namespace (see Avango.h).
  • Insert documentation blocks for all top-level entities (file, class, enum, struct, union, typedef, defines) and add them to the correct group. This must be done for each top-level entity.
  • Document function arguments only when necessary (speaking names).
  • Comments for base class functions must not be replicated in the derived class.
  • Start sentences with capital letters (correct orthography!).

Format for Header Files

  • File extension is '.h'
  • Filename same as classname (ClassName.h)
  • Add an enclosing namespace to all declarations and definitions, e.g.
    namespace av
    {
      ...
    }
    
  • Virtual functions are only explicitly declared as such at the introduction in the base class virtual f();
  • Inherited virtual functions are commented to be virtual: /* virtual */ f();
  • Avoid using inline functions (exceptions for template functions)
  • Prototype: ClassName.h
  • Specify default parameters only in header file, don't repeat them in implementation (nor commented out)

Format for Implementation Files

  • File extension is '.cpp'
  • Filename same as classname (ClassName.cpp)
  • Make everything top-level (no enclosing namespace)
  • Break apart return value from function name and add commented additional specifiers (static, virtual)
    /* virtual */ void
    doSomeThing(int param1, int param2)
    {}
    
    /* static */ int
    someClassFunction()
    {}
    

Subversion Guidelines

  • Use correct  MIME Media Types (especially for binaries), e.g.
    % svn propset svn:mime-type "application/pdf" some.pdf
    
  • Auto-props are used to set properties on newly added files based on their filenames. Functionality can be configured by setting options in ~/.subversion/config. All entries which match will be applied to the file. Prototype:
[miscellany]
enable-auto-props = yes

*.c = svn:eol-style=native
*.c++ = svn:eol-style=native
*.cpp = svn:eol-style=native
*.gif = svn:mime-type=image/gif
*.h = svn:eol-style=native
*.html = svn:eol-style=native;svn:mime-type=text/html
*.ico = svn:mime-type=image/x-ico
*.jpg = svn:mime-type=image/jpeg
*.m4 = svn:eol-style=native
*.ml = svn:eol-style=native
*.mli = svn:eol-style=native
*.pdf = svn:mime-type=application/pdf
*.png = svn:mime-type=image/png
*.py = svn:eol-style=native
*.rgb = svn:mime-type=image/x-rgb
*.scm = svn:eol-style=native
*.sln = svn:eol-style=native
*.sgi = svn:mime-type=image/x-sgi
*.sgm = svn:eol-style=native;svn:mime-type=text/sgml
*.sh = svn:eol-style=native;svn:executable
*.tif = svn:mime-type=image/tiff
*.txt = svn:eol-style=native
*.TXT = svn:eol-style=native
bootstrap = svn:eol-style=native;svn:executable
Makefile* = svn:eol-style=native
SConscript = svn:eol-style=native
SConstruct = svn:eol-style=native

References