Version 5 (modified by patrick, 17 years ago) (diff) |
---|
Style Guide for Orxonox C++ Code
'Coding style' refers to the way source code is formatted. For C++, this involves things like brace placement, indentation, and the way parentheses are used. The most important thing is for the code to be consistent within a program or library - code with sloppy formatting is not acceptable, since it is hard to read.
When writing a new program or library, please follow a consistent style of brace placement and indentation. We recommend the following code style.
Remember that any violation to the guide of course is allowed if it enhances readability.
Files
Header and Source
Keep your classes/files short, don't exceed 2000 LOC (if it get's longer you may separate functions into different modules). Put every class in a separate file and name the file like the class name (don't use CamelCase names separate them with underlines). Create a separate header (ends with .h) and source file (ends with .cc). Example for class MyExampleClass.
file names: my_example_class.cc my_example_class.h
Namespaces
Create a directory for every namespace (== create a directory for every modules and all its submodules).
Inlineing and Templates
Inline functions and template structures should be declared in a .h header file as described above but implemented in a *-inl.h file (since templates are normally not implemented in a source .cc file).
Machine-Dependent Code
Place machine-dependent code in a special file so that it may be easily located when porting code from one machine to another.
80 Columns at Maximum
File content must be kept within 80 columns. Comment: 80 columns is a common dimension for editors, terminal emulators, printers and debuggers, and files that are shared between several people should keep within these constraints. It improves readability when unintentional line breaks are avoided when passing a file between programmers.
Comments
Introductory Comment
Every file that contains source code must be documented with an introductory comment that provides information on the file name and its contents:
//
Naming Conventions
Classes and Types
Names representing types must be in mixed case starting with upper case.
class SavingsAccount { }; struct SimpleStruct { };
Variables
Variable names must be in mixed case starting with lower case. Each variable declaration on a new line. Avoid abbreviations in names.
string testString; int numberOfTimes;
Memeber variables of classes all end with an underline:
class TestClass { private: int numberOfTimes_; };
Use useful names:
// wrong ProgressBar *prbar; string prtxt, errstr; // correct ProgressBar* downloadProgressBar; string progressText; string errorString;
Comment: Apart from its name and its type, the scope of a variable is its most important feature. Indicating class scope by using underscore makes it easy to distinguish class variables from local scratch variables. This is important because class variables are considered to have higher significance than method variables, and should be treated with special care by the programmer.
Constants ==
Named constants (including enumeration values) must be all uppercase using underscore to separate words. Always use constants instead of numbers.
const int MAX_ITERATIONS = 5; for (int i = 0; i < MAX_ITERATIONS; i++) {} // Instead of (... i < 5; ...)
Functions
Names representing methods or functions must be verbs and written in mixed case starting with lower case. Avoid abbreviations in names.
void calculateTheLowerBoundary() {} int howManyItemsLeft() {}
For interface functions to local member variables use short functions (setter and getter functions):
class WorldEntity { public: inline string Name() { return name_; } inline void setName(const string& name) { name_ = name; } private: string name_; };
The name of the object is implicit, and should be avoided in a method name.
class Line { public: float getLength(); // Not getLineLength() since it's clear that it is a line. };
Enumerations
Enumeration constants can be prefixed by a common type name.
enum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE };
Namespaces
Names representing namespaces should be all lowercase.
namespace ioutil { }
Indentation
Spaces
Use 2 spaces for an indentation level. Never use tabs, as it is common in windows IDEs.
Whitespaces
Use one space after each keyword
Special Implementations
Use STL Libraries
Use STL (standard template library) implementations of common abstract data structures like lists, arrays, stacks, queues, never implement your own!
General Topics
- different build targets possible (for subprojects)
- different make options (make-dbg, make-opt)
- unit test supported (in debug mode)
- compiler mode: warnings being treated as errors
Code Reviews
Code review is a pretty simple process: at its heart, it is little more than reading some code written by someone else. Nevertheless, it can be useful to have a set of things on which to focus during a review:
- Does the branch merge or the diff apply cleanly?
- Are there unit tests for the code being changed or added?
- Do the unit tests pass for you?
- Do the unit tests pass for buildbot?
- Is there documentation for new code?
- Where appropriate, has existing documentation been updated (including ChangeLog?/NEWS files)?
- Does the code adhere to the coding standard?
There's the easy list. Most are mechanical checks. Don't feel bad about rejecting a branch if the answer to any of these questions is no: the problems may seem minor in isolation, but each contributes to overall poor code quality. Moreover, sometimes apparently minor problems can be hiding larger issues.