Source File Style
Many of the rules of the FreeBS kernel style can be applied.
Exceptions or Clarifications
-
Source file names are all in lower case and use underscores for name separation.
-
Every source code file starts with a copyright statement. The copyright date should be checked, when a file is edited, and adjusted to meet current date.
/*
* Copyright (C) 2014-2019 CZ.NIC
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
-
Use tabs for indentation.
- Tabulators are considered to be 8 characters wide when displaying the code or when computing character columns.
- Tabulators are used for block indentation.
- When continuing with function parameters or expression that didn't fit the first line then the parameters/expression are shifted additional four spaces (not a tab) on the second line. Should a similar issue occur on next (third) line, then additional 4 spaces may be added again (resulting in 8 spaces - not a tab). Should a similar issue arise again (fourth line) when continuing the line (expression/function call is too long) then rather change the code instead of continuing with this mess.
-
Typedefs are generally not OK.
- They can create confusion especially when mixed with some keywords such as
const
. - The only legitimate usage of a
typedef
are:- When working with a nested type a function or a method where the visibility of the
typedef
is local. - Should a template expansion inside a template situation occur (e.g. to avoid errors when working with
foreach
).
- When working with a nested type a function or a method where the visibility of the
- They can create confusion especially when mixed with some keywords such as
-
preprocessor statements
- We used
#ifndef _HEADER_FILE_H_
as header guards (for file header_file.h). Leading and trailing underscore were mandatory. - Nowadays we use a
#pragma once
header guards. - The
#endif
statement is followed by comment specifying corresponding#ifdef
or#if
statement (i.e.#endif \* _HEADER_FILE_H_ *\
) - We use
#else
statements followed by a comment with the negation of the condition that leads to the else statement. - We prefer C-style commentaries.
- We used
-
Functions visible only inside a compilation unit (.c or .cpp file) must be
static
. -
order of includes
- system headers (currently we don't need them)
- 3rd party libraries (those with angle brackets)
- header files from our project (those with double quotes)
- Groups are separated by one empty line.
- Each group is sorted alphabetically according to the strings occurring in the brackets or quotes.
-
commentaries and documentation
- We use Doxygen-style comments.
- Comment functions and methods before their declaration in the header files. In general, every function, method, structure, class, union or enumeration type hast to be commented at some place.
- It's OK to use comments inside function bodies for clarification.
-
capitalisation
- Class names begin with capital letter (e.g. class MyClass, not my_class, myClass, MYCLASS, etc.).
- Enumeration types begin with capital letter.
- Enumeration values consist of capitals and underscores only.
- Defined constants are capitals and underscores only.
- When declaring a function working with structures (not classes) and enumeration always use
struct
andenum
.
-
function and variable declaration and definition
-
Never declare or define functions with empty brackets. Always use
void
. - When defining/declaring a reference or pointer, always attach the
*
or&
to the variable:-
void func(struct A *a)
(notvoid func(struct A* a)
norvoid func(struct A * a)
) -
const MyClass &ref
(notconst MyClass& ref
norconst MyClass & ref
) -
int *func(void)
(notint* func(void)
norint * func(void)
)
-
- When defining default parameter, then always put a single space around the
=
.-
void func(int i = 0)
(notvoid func(int i=0)
)
-
- There must not be a space between a function name and the opening bracket.
-
Never declare or define functions with empty brackets. Always use
-
type casting
- When casting types to different types always attach the closing parenthesis directly to the cast value/variable:
-
(unsigned long)a
(not(unsigned long) a
)
-
- When casting pointer types, always leave a single space character between the asterisk and type name:
-
(int *)b
(not(int*)b
)
-
- When casting types to different types always attach the closing parenthesis directly to the cast value/variable:
-
templates
- When defining or using types based on templates never place the opening ant closing pointy brackets in such manner that they could be interpreted as
<<
or>>
.-
QMap<int, QPair<int, int> >
(notQMap<int, QPair<int, int>>
)
-
- When defining or using types based on templates never place the opening ant closing pointy brackets in such manner that they could be interpreted as
-
null pointers
- Don't use
0
to initialise null pointers. - Don't use
0
to compare pointers to null value. - Don't use implicit conversion to
bool
when checking for null pointers (i.e. don't useif (ptr) ...
norif (!ptr) ...
). - Use
Q_NULLPTR
to initialise pointers and test for null value.- The value
Q_NULLPTR
is preferred when checking pointers to Qt objects, values and custom defined C++ objects.
- The value
- Use
NULL
when dealing with pointers onto structures and other values that originate from C code.
- Don't use
Doxygen
- The style is a mix of the Qt and Java style.
-
/*!
, not/**
-
@brief
, not\brief
-
- order of sections:
- brief description
- long description
- notes
- warnings
- references
- parameters
- return values
- todos
- Always use
@brief
(no autobrief). - Indent text (using spaces only) in multiple-line sections.
- In multi-line comments, opening line (
/*!
) should be empty. - One empty line between two consecutive sections.
- Structure and union members documented on the same line if the comment fits. This also applies to non-function non-method class members.
- Use
@return
for describing return values. Usage of@retval
(or more of them) instead of `@return if the function returns some distinct values (such as 0 for no error, -1 for something else, etc.) is also encouraged. - We don't use file comments currently.
- Every API function/method must have a comment containing at least:
- a brief description
- parameters (if applicable)
- return values (if applicable)
- Functions and methods are commented upon their declarations in the header files. (The only exceptions are static functions.)
/*!
* @brief Some class.
*
* Longer description.
*/
class SomeClass : public QObject {
Q_OBJECT
public:
/*!
* @brief Constructor.
*
* @param[in] parent Parent object.
*/
explicit SomeClass(QObject *parent = Q_NULLPTR);
...
private:
const QString name; /*!< Some name. */
QByteArray value; /*!<
* This description does not fit on a single line
* because it is rather verbose.
*/
};
/*!
* @brief This is a function doing something.
*
* Longer description of what it really does.
*
* @note Nobody actually knows what it really does.
*
* @warning Use this function at own risk.
*
* @see anotherFunction()
*
* @param[in] par1 Some parameter.
* @param[out] par2 Data to be processed.
* @retval 0 on success
* @retval -1 on any error
*
* @todo Remove (deprecated).
*/
int someFunction(const QString &par1, QByteArray &par2);
Project File
-
SOURCES
,HEADERS
,FORMS
and other groups are sorted alphabetically according to the strings describing the relative path to the respective files.
If you are not sure about how to write some code see inside some existing modules (e.g. tag_item
, table_model
).