FMG Programming Guidelines

The FMG Programming Guidelines (FPG) collect basic rules when creating software assets for the FMG. When following these guidelines, new programmers should have a smooth entry into our code, and seasoned FMG programmers can read new code written by others more easily.

The FPG are based on our own experiences, as well as a few external documents. Most notably, these external documents are the BOOST Guidelines and Chapter 1 from The Practice of Programming (TPOP) by Brian W. Kernighan and Rob Pike. We tried our best to adhere to the three cornerstones of TPOP:

  • Simplicity
  • Clarity
  • Generality

Have fun working for the FMG!

Identifier Naming Conventions

Tell me your name, and I will tell you who you are.

Naming entities in code is an issue of neverending debate. We do not try to give a definite answer, but mandate the following rules for code that lives in the FMG's CVS repository. Our main intention was to simplify reading code without a sophisticated IDE. The rules are intended for C/C++, Java and related languages. First, here are some general rules:

  • Identifiers should be spelled in English, because this makes working in an international environment much easier.
  • In general, be verbose for names that belong to public interfaces.
  • For local names it is OK to use briefer ids, but still try to give them meaningful names. Try to avoid abbreviations that are not common practice.
  • Use idiomatic identifiers for local ids like loop counters (i, j, k) and pointer variables (p, q), and do not use these names elsewhere.
Class Name
First letter uppercase, new words also start uppercase, concatenate words without separation character.
Example: AutomataGenerator
Data Member/Attribute
Prefix m_, all lowercase, concatenate words with underscore character.
Example: m_token_list
Method/Member function
First letter lowercase, new words start uppercase, concatenate words without separation character.
Example: getFirstToken
Free Function
All lowercase, new words start uppercase, concatenate words concatenate words with underscore character.
Example: count_states
Type Aliase (C++ typedef)
Suffix _t, all lowercase, concatenate words with underscore character.
Example: token_iterator_t
Local Id
All lowercase, concatenate words with underscore character.
Example: current_token
Constant
Prefix c_, all lowercase, concatenate words with underscore character.
Example: c_pi
Global Id
Prefix G_, all lowercase, concatenate words with underscore character.
Example: G_init_token
Namespace
All lowercase, concatenate words with underscore character.
Example: fmg
Pointer Variable
Follow rules according to the variable's category. Then add suffix _p.
Examples: new_token_p, m_first_token_p
Macro
All uppercase, concatenate words with underscore character.
Example: LINUX_26

Code Layout

These basic conventions enable working with the editor of your choice and having a decent layout without major tweaking.

Tabs vs. Spaces
Never use tab characters in files! Of course it is OK to press tab in your favorite editor, but make sure it always inserts spaces for indentation.
Emacs: [TODO]
Line Length
Try to stay within 80 characters. Of course, this is not feasible all the time, however it eases printing.
Indentation
Indent by 2 spaces. Indentation should be applied whenever opening a new scope, like class definitions, compound statements (if, for, while), function definitions, and so on.
Brace Position
Put the brace on a line of its own for class and function definitions, otherwise put them on the same line. Avoid compound statements without explicit braces, even if the compound is made up of only one statement. For long scopes, repeat the opening context at the closing brace.
Expressions
Basically, follow the guidelines given in TPOP: Add space before and after operators (unless to indicate grouping in lengthy expressions), use parentheses to indicate operator precedence and associativity, add space after colons, separate expressions from statements with space.
namespace fmg
{

  class Dummy
  {
    static int max(int m, int n)
    {
      if (m >= n) {
        return m;
      }
      else {
        return n;
      }
    }
  }; // class Dummy

} // namespace fmg

File Structure and Naming

File Name Extensions
C++ implementation files have the extension cpp, header file end in hpp., For C, use c and h.
File Names
File names should be given the name of the class residing inside. This implies that usually every class should go into its own files (header & implementation).
Very short classes (e.g. function objects) should go into the file pair common.cpp and common.hpp.
Directory Structure
The typical layout of a code project has this top level directory structure:
  src/
  obj/
  doc/
  README
  INSTALL
  Changelog
Header Policy
Every header should contain a header guard. The macro name is composed like this: __ + filename + _ + creator initials + __
  #ifndef __DUMMY_HPP_RJW__
  #define __DUMMY_HPP_RJW__
  ...
  #endif
Do not use using directives or using declarations in header files! Instead, please provide the fully qualified name:
  #include <vector>
  int print(std::vector& v);

Documentation

In this section we talk about source documentation only. However, source documentation is divided into two topics: interface and code documentation. Interface documentation should be aided by tools, and code documentation is up to the discretion of the programmer.

Interface documentation

We use doxygen for source documentation. So first have a look at the introduction at its homepage to get an idea of the basic concepts and features.

Code documentation