|
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
|