Code Style Guide: Difference between revisions
(→Tags) |
(Always use brackets) |
||
Line 76: | Line 76: | ||
} | } | ||
'''if'''(foo) | '''if'''(foo) { | ||
bar = 1; | bar = 1; | ||
} | |||
'''if'''( x >= min.x | '''if'''( x >= min.x |
Revision as of 16:37, 13 May 2016
This page describes the style used for Arx Libertatis source code. New contributions should try to follow this guide, even if much of the existing code doesn't. However, nothing described here are is a strict rule and
Example
(WIP!)
src/somedir/SomeClass.h:
/* * Copyright notice(s) ... */ #ifndef ARX_SOMEDIR_SOMECLASS_H #define ARX_SOMEDIR_SOMECLASS_H namespace somens { //! Short documentation comment void someFunction(); class SomeClass { public: /*! * Longer documentation comment * * \param functionParameter Some parameter... * * \return some value. */int
memberFunction(int
functionParameter);int
m_memberVariable; staticint
s_staticMemberVariable; }; externint
g_globalVariable; } // namespace somens #endif // ARX_SOMEDIR_SOMECLASS_H
src/somedir/SomeClass.cpp:
#include "somedir/SomeClass.h" namespace somens {int
g_globalVariable =0
;int
SomeClass::s_staticMemberVariable =0
;int
SomeClass::memberFunction(int
functionParameter) {int
localVariable = functionParameter; someFunction(); return localVariable + m_memberVariable; } } // namespace somens
if(foo) { a = Template:Text; i++; } else if(bar) { a = Template:Text; j++; } else { a = Template:Text; k++; }
if(foo) { bar = 1; }
if( x >= min.x && x <= max.x && z >= min.z && z <= max.z && !(type & (FLAG_A | FLAG_B | FLAG_C)) && foo ) { bar = 1; }
switch(bar) { case 0: { ++bar; break; } case 1: { --bar; break; } default: { bar += bar; break; } }
switch(bar) { case 0: ++bar; break; case 1: --bar; break; default: bar += bar; break; }
for(int
i =0
; i <10
; i++) { // do stuff }
for(int
i =0
; i <10
; i++) for(int
j =0
; j <10
; j++) for(int
k =0
; k <10
; k++) { foo[i][j][k] = 123; }
while(condition) { // ... }
do { // ... } while(condition);
try { number = boost::lexical_cast<long
>(string); } catch(...) { number =-1
; }
Note: C++-style static_cast
etc. are usually preferred.
char
* s = (char
*)object;
class Point { public: Point(Template:Real x, Template:Real y) : x(x) , y(y) { // ... } private: Template:Real x; Template:Real y; };
Symbol Names
Symbol names use variants of Template:Wp.
Classes
Classes and structs use camel case names and start with an upper case letter:
struct SomeType;
TODO: what about typedefs?
Functions
Function names are also camel case, but start with a lowercase letter:
void someFunction();
Member functions
Member functions are also just functions - there is no need for a different visual style.
Variables
Variable names should describe what the variable is used for, not it's type. Particularly, hungarian notation ("pVariable", "iVar") and variations "varPtr" should not be used.
Local variables
Local (function-scope) variables use camel case names with a lower-case start:
int
localVariable = 0;
Function parameters
Function parameters are local variables, so they should follow the same naming scheme.
Member variables
Member variables should be named just like local variables, but with an added m_
prefix:
class SomeClass {
int
m_someVariable;
};
The prefix makes it easy to distinguish local variables from those with a longer lifetime.
Static member variables
Static member variables should be named just like local variables, but with an added s_
prefix:
class SomeClass {
static int
s_someVariable;
};
The prefix makes it easy to distinguish local variables from those with a longer lifetime.
Static function-scope variables
No special formatting rules are necessary.
Global variables
... should be avoided if possible! But for the cases where they are needed, they should be named just like local variables, but with an added g_
prefix:
int
g_someVariable =0
;
The prefix makes it easy to distinguish local variables from those with a longer lifetime.
Namespaces
Namespace names should be lowercase and as short as possible.
If the namespace block contains more than a few lines, consider repeating the namespace keyword and name at the end:
namespace ns { // ... } // namespace ns
Low-level symbols
Low-level classes and their member functions and variables (container, path, ...) use C++-stdlib-style lowercase names with underscores. This is so that they visually fit in with other lower-level symbols from the C++ stdlib and Boost.
Formatting
Line length
Indentation
Use a single tab character for each indentation level. This allows everyone to choose their own indentation with by configuring their editor.
Also indent "empty" lines according to the indentation of adjacent lines.
if(...) { // ... }
Alignment
Always uses spaces for alignment, never tabs:
if(...) { function(arg, arg, arg, arg, arg); }
Line breaks
Other whitespace
#include
s
Syntax
For system and library includes, use angle brackets:
#include <header>
For our own includes use quotes and include the full path below the src
directory:
#include "subsystem/File.h"
Order
- First include should be the header corresponding to the current source file
- Then come standard C/C++ includes
- After that, other system includes (
<unistd>
, etc.) - Next, library includes
- Finally, includes for our own header files
There should be an empty line between each of these groups of includes. More empty lines may be added to aid readability (but if that is needed, consider splitting the source file to reduce the number of includes).
Within each group, #include
s should be sorted semi-lexicographically: Within each path hierarchy, entries are sorted lexicographically, except that all files always come before subdirectories.
Example (subsystem/File.cpp
):
#include "subsystem/File.h" #include <string> #include <vector> #include <boost/foreach.hpp> #include "a/Header.h" #include "a/another/Header.h" #include "b/Header.h"
Documentation
For doxygen comments use either
//! …
or
/*! … */
variants.
Comments at the end of a line should use
//!< …
to signify what the comment belongs to.
All other doxygen comment variants should be avoided.
Use '\' for commands, not '@':
/*! * \brief Something that does something * * \param name the one and only parameter. * * \return a value. */
Other notes
iterators
Always prefer pre-increment (++i) over post-increment (i++) for non-builtin types.
using namespace
statements
... should be avoided. Use namespace aliases instead:
namespace a = b::c::d;
However, try to use a meaningful alias. If possible, consistent aliases should be used in different files for the same source namespace.
other using
statements
... are also usually best avoided. There are of course exceptions (for example to invoke ADR with std::swap
), but leaving the namespace prefix where the symbol is used makes it easier to tell where the symbol comes from.
#include
guards
Commit messages
Title
The first line of the commit message should be a short description of what the commit does. It should use the imperative tense (it's generally shorter), should not end in any punctuation, and the first word should be capitalized (unless it's a code reference).
It can optionally be preceded by the component is modifies, followed by a colon and space ": " and/or by the tool used to find the bug (enclosed in array brackets: "[tool] …).
If the change in the commit cannot be summarized in a short pseudo-sentence it is a good indicator that the commit should be split up.
Good commit titles:
Frobnicate the knobs FooBar: Frobnicate the knobs [foo] Frobnicate the knobs
Non-comformant commit titles:
frobnicate the knobs Frobnicate the knobs. Frobnicates the knobs Frobnicated the knobs This commit does this and and it also does this
Body
The commit message body can contain any free-form text but should try to keep lines shorter than 80 characters.
Tags
Optionally, commit messages can be annotated with one more tag. Tags should come after the message body (separated by an empty line). Each tag should begin at the start of its own line.
Bugs
Commits fixing a bug should be have the following tag at the end:
Fixes: bug #42
"bug" can be replaced with "issue" or "crash report".
Feature/enhancement requests should use:
Implements: enhancement #42
"enhancement" can be replaced by "feature request".
If the commit only partially fixes a bug, mention that in the commit message and use this tag instead:
See: bug #42
Using these tags is not mandatory but makes the commit corresponding to a bug easier to find.
Commit references
To reference other commits either mention "commit $hash" in the message body or use:
See: commit $hash
You can use the full commit hash or any prefix that is at least 5 (preferably 7) characters long.
Sign-off
Use of the Signed-off-by tag (git commit --signoff
) is not required but forbidden either.