[Uml-devel] Coding Style - v2
Andi Fischer
andi.fischer at hispeed.ch
Thu Jul 10 20:35:25 UTC 2008
Hi everybody,
Here is version 2 of our coding style. I added the inputs from Sharan
and Gopala.
Still okay?
Thanks,
Andi
----- CODING-STYLE
------------------------------------------------------------------------
Umbrello coding style
=====================
A lot of successful software projects like Linux [1], boost [2], or
Qt [3] have their own coding style guide. A coding style guide improves code
quality, readability, and serves as a guideline for new developers.
Every file in Umbrello will sooner or later be ported by applying the
guidelines
described in this document. Every developer should at least consider the
points
made here. And sometimes, there may be a good reason to break a rule.
Some of the rules are already automatic tested by Krazy [6] every day.
References:
-----------
[ 1] http://lxr.linux.no/linux/Documentation/CodingStyle
[ 2] http://www.boost.org/development/requirements.html
[ 3] http://doc.trolltech.com/qq/qq13-apis.html and
http://trolltech.com/developer/resources/notes/naming
[ 4] http://techbase.kde.org/Policies/Kdelibs_Coding_Style
[ 5] http://techbase.kde.org/Policies/Licensing_Policy
[ 6] Krazy - http://www.englishbreakfastnetwork.org/
[ 7] http://techbase.kde.org/Policies/Library_Code_Policy
[ 8] astyle - http://astyle.sourceforge.net/
[ 9] apidox -
http://techbase.kde.org/Development/Tutorials/API_Documentation
Formatting:
-----------
* Indentation:
1.) Do not use tabs [4].
2.) Indentations are 4 characters deep [4].
* Whitespace:
3.) Do not leave whitespaces at the end of lines.
4.) Use blank lines to group statements [4].
5.) Use only one empty line to separate items [4].
6.) Use one space after each keyword [4].
Example:
if( // wrong
if ( // correct
7.) Usage of whitespaces between an opening and closing parenthesis
(e.g. if- and for-statments, function calls) is up to the developer.
Example:
if (i < 5) <-> if ( i < 5 )
calculateSalary(age, years); <-> calculateSalary( age, years );
8.) For pointers or references, use
either a single space after '*' or '&', but not before (C++ style),
Example:
T* v and T& v
Beware:
char* i, j; // i is declared pointer to char, while j is
declared char
or a single space before '*' or '&', but not after (C style).
Example:
T *v and T &v
9.) No space after a cast [4].
10.) Do not use spaces around '.' or '->',
nor between unary operators and operands.
* Braces:
11.) Function implementations, class, struct and namespace declarations
always have the opening brace on the start of a line [4].
12.) For all other constructs (if, switch, for, ...), the left curly brace
goes on the same line as the start of the statement [4].
13.) Use curly braces even when the body of a conditional statement
contains
only one line [4].
* Statements:
14.) Do not put multiple statements on a single line.
* Switch statements:
15.) Case labels are on the same column as the switch [4].
* Line breaks:
16.) Try to keep lines shorter than 100 characters, inserting line breaks
as necessary [4].
* Pointers:
17.) In C++, a null pointer is 0; not 0l, 0L or NULL.
Variable declaration:
---------------------
18.) Each variable declaration on a new line [4].
19.) Variables and functions start with a lowercase letter.
20.) Classes always start with a capital letter.
21.) Each new word in a name starts with a capital letter [4].
22.) Member variables start with "m_".
23.) Do not use pseudo Hungarian style.
Example:
m_bSomeBoolean, m_pSomePointer // wrong
m_someBoolean, m_somePointer // correct
24.) Variables (objectName) in ui files start with "ui_".
Rationale:
This makes it possible to identify the source of the variable
(defined in class or in ui file).
25.) Use vertical alignment to ease scanning of declarations.
Example:
QString aStringToUse;
int anInt;
double aDoubleNumberToUse;
26.) Use static const variables instead of defining integers or floats.
Rationale:
This provides type-safety.
Casting:
--------
27.) Use C++ style cast like static_cast, dynamic_cast instead of C style
cast as it asserts the purpose of the cast.
Also try to use Qt casts like qobject_cast, qgraphicsitem_cast in
place of dynamic_cast wherever possible as the Qt style casts succeeds
even across libraries.
It doesn't mean dynamic casts shouldn't be used though. Use them
wherever it is impossible to use Qt's cast.
License:
--------
28.) All source code and related data files must have the following
license header from the first line on of the file (see also [5],
checked by Krazy [6]).
/*
Copyright <year> Umbrello UML Modeller Authors <uml-devel at uml.sf.net>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
Includes:
---------
29.) Include own header first (checked by Krazy [6]).
30.) Use QtModule/QClass in angle brackets (checked by Krazy [6]).
31.) Use KDE/KClass in angle brackets (checked by Krazy [6]).
32.) Do not add a path to the include statement.
Example:
#include "../uml.h" // wrong
#include "uml.h" // correct
Rationale:
Paths are set in the make files. Rearranging or moving files
should not be followed by source code editing.
33.) Header includes should be listed in the following order and grouped:
- own header
- Umbrello includes
- KDE includes
- Qt includes
34.) The headers inside each group should be sorted.
Rationale:
For ease of locating them.
Tip:
Kate/KDevelop users can sort the headers automatically.
Select the lines you want to sort, then
Tools -> Filter Selection Through Command -> "sort".
In vim the same can be achieved by marking the block, and then
doing ":sort".
In emacs, you can mark the block and then do "M-x
sort-lines".
35.) Includes in a header file should be kept to the absolute minimum, as
to keep compile times low. This can be achieved by using forward
declarations.
Forward declarations work for pointers and const references.
Include guards:
---------------
36.) Include macro characters are all in uppercase letters.
Example:
#ifndef MyFileName_h // wrong
#ifndef MY_FILE_NAME_H // correct
37.) Do not use leading or trailing underscores on the include guard macro
as they are reserved for compiler/libc use (checked by Krazy [6]?).
Example:
#ifndef _MY_FILE_NAME_H_ // wrong
#ifndef MY_FILE_NAME_H // correct
Doxygen comments:
-----------------
38.) Every public item must have a doxygen comment.
39.) Doxygen comments look like (see also [9]):
/**
* Here is the description...
* @param ... ...
* @return ...
*/
40.) The comments should be written in the implementation file (cpp).
Rational:
The header files can be overviewed easier and read quicker.
Header structure:
-----------------
41.) According to policy, a C++ header file should contain only 1 publicly
visible class.
<license>
<include guard>
<includes>
namespace
{
class <name> : public <parent>
{
public:
protected:
private:
};
}
C++:
----
42.) "const correctness" should be preserved as much as possible.
Make all getters const.
43.) It might be a good idea to make the constructors explicit
(checked by Krazy [6]).
Metrics:
--------
- loc = lines of code
- Refactor classes, which have more than 1000 loc per class.
- Refactor methods, which have more than 200 loc per method.
Astyle:
-------
You can use astyle to format one or several files with the following
command:
astyle --indent=spaces=4 --brackets=linux \
--indent-labels --pad=oper --unpad=paren \
--one-line=keep-statements --convert-tabs \
--indent-preprocessor \
`find -type f -name '*.cpp'` `find -type f -name '*.h'`
or
astyle --indent=spaces=4 --brackets=linux \
--indent-labels --pad=oper --unpad=paren \
--one-line=keep-statements --convert-tabs \
--indent-preprocessor \
< Original > Beautified
This applies some of the rules in section 'Formatting'.
Krazy:
------
The Perl script Krazy checks the code every day for some rules and lists
the failed items on its web site (see [6]).
More information about the umbrello-devel
mailing list