Coding Style (C++)#
This is an overview of the coding conventions we use when writing C++ code for the Open Chemistry projects. The style is based largely on the Qt and KDE styles.
Code formatting is enforced through use of the clang-format tool.
Indentation#
2 spaces are used for indentation
Spaces, not tabs!
Line Width#
Keep lines of source code to less than 80 characters wide.
Declaring Variables#
Declare each variable on a separate line
Avoid abbreviations (e.g. “a”, “nmbr”) where possible
Single character variable names are fine for counters, temporary variables etc where the purpose is obvious
Wait until a variable is needed to declare it, don’t keep unused ones around
// Incorrect
int nmbr, f;
// Correct
int number;
int result;
Variables and function names start with a lower case letter, with other words using camel case
Abbreviated names should be avoided
Acronyms are camel-cased (e.g. CmlFormat, not CMLFormat)
// Incorrect
double Cntr;
std::string rawXML;
char LIST_DELIMITER = '\t';
// Correct
double center;
std::string rawXml;
char listDelimiter = '\t';
Class names always start with an upper-case letter
Public classes should be placed inside the appropriate namespace
Member variables should start with m_
Whitespace#
Use blank lines to group statements together where appropriate
Only use a single blank line
Always use a single space after a keyword and before a curly brace
// Wrong
if(blah){
explode();
return 5;
}
// Correct
if (blah) {
explode();
return 5;
}
For pointers or references, always use a single space between the type and the ‘*’ or ‘&’, but no space between that character and the variable name.
char *x;
const std::string &myString;
const char * const y = "whoah";
Surround binary operators with spaces
No space after a cast
Avoid the use of C-style casts
// Incorrect
char* memoryBlock = (char*) malloc(data.size());
// Correct
char *memoryBlock = reinterpret_cast<char *>(malloc(data.size()));
Braces#
The left curly brace normally goes on the same line as the start of the statement
//Incorrect
if (foo)
{
run();
break;
}
// Correct
if (foo) {
run();
break;
}
Exception: if this is class declarations and function implementations. The left brace always goes on the start of a line there
void myFun(const std::string &name)
{
std::cout << "Supplied name: " << name << std::endl;
}
class Bar
{
public:
Bar();
};
Use curly braces when the body of a conditional contains more than one line, and also if a single statement is complex
// Incorrect
if (!correct) {
return false;
}
for (int i = 0; i < 42; ++i) {
var += i;
}
// Correct
if (!correct)
return false;
for (int i = 0; i < 42; ++i)
var += i;
Exception: Use curly braces if the parent statement does not fit on one line/wraps
// Correct
if (!correct || !isValid
|| !aGoodDay) {
return false;
}
Exception: Use curly braces in any if, then, else blocks where any of the elements cover several lines
// Incorrect
if (!correct)
return false;
else {
++counter;
return true;
}
// Correct
if (!correct) {
return false;
}
else {
++counter;
return true;
}
// Incorrect
if (a)
if (b)
return true;
else
return false;
// Correct
if (a) {
if (b)
return true;
else
return false;
}
Use curly braces when the body is empty.
// Incorrect
while (true);
// Correct
while (true) {}
Parentheses#
Parentheses should be used to group expressions, and to make the intent clearer
// Incorrect
if (a && b || c)
// Correct
if ((a && b) || c)
// Incorrect
x = a + b & c;
// Correct
x = (a + b) & c;
Switch Statements#
The case labels should be in the same column as the switch
Every case must have a break/return statement at the end, or a comment to indicate the omission
Exception: Another case follows immediately
switch (myEnum) {
case LINE:
drawLine();
break;
case POINT:
case VERTEX:
drawDot();
// Fall through to default.
default:
drawDefault();
break;
}
Line Breaks#
Keep lines shorter than 80 characters; insert breaks if necessary
Commas go at the end of a broken line
Operators go at the beginning of a new line
// Correct
if (veryLongExpression()
&& anotherEvenLongerExpression()
&& justWhenYouThoughtItCouldntGetLonger()) {
doSomething();
}
Eigen::Vector3d position(currentPosition.x() + offset,
currentPosition.y() + offset,
0);
Inheritance and the “virtual” Keyword#
When reimplementing a virtual method, do not put the “virtual” keyword in the header
Referencing Members#
The use of this-> is discouraged. The use of the m_ prefix should make it clear that a member variable is being referenced.
File Naming#
All file names should be lower-case.
C++ source files should have a .cpp extension.
C++ header files should have a .h extension.
Breaking Rules#
As with Qt, and others, feel free to break a rule if it makes your code look bad!