Skip to main content

C++ Style and Documentation

This section introduces a style guide for consistently phrasing and documenting C++ code. Consistency is key to making a codebase readable. You don't want the code to look like it was written by a 100 different people.

If you don't know any C++, you shouldn't read this section very carefully yet. We use this style in our C++ code examples. However, be aware that part of professionally developing code is being consistent.

We use the Google C++ Style Guide. We won't repeat every single rule, but we'll give you the highlights to get started. Make sure to read through their style document thoroughly.

General Style Rules​

Function Names​

Function names should be camel case.

void MyFunction() {
}

Function Variable Names​

Function variable names should be snake case:

void MyFunction() {
int my_var;
}

Class Names​

Class names should be camel case.

class Hello;

Method Names​

Method names should be camel case

class Hello {
public:
void MyFunction() {
}
};

Class Variable Names​

Class variable names should be snake case and be appended with a trailing "_". The underscore makes it so that we know this is a variable of the class, and not just a typical variable stored on the stack.

class Hello {
int my_var_;
};

Namespaces​

Generally, classes should be encapsulated in a namespace. This avoids accidental conflicts across packages.

Namespaces are snake case. Namespaces must also be terminated using a comment which states the name of the namespace.

namespace my_namespace {

} // namespace my_namespace

Enumerations​

Enumerations should be camel case. Enumeration entries should begin with a lowercase k.

enum class MyFruitEnum {
kApple,
kOrange,
kDragonFruit
};

Macros​

Macros should be snake case and all caps. Macros should be used sparingly since they are much harder to debug. The most common use of macros is for defining constants.

#define MY_MACRO 25

Macro function parameters should be snake case and all caps as well.

#define MY_MACRO(A, B)

Conditionals & Loops​

Whenever making a conditional, ensure there is a single space between the keyword and the parenthesis.

// This is BAD
if(true) {
std::cout << "hello" << std::endl;
}

// This is GOOD
if (true) {
std::cout << "hello1" << std::endl;
} else if (false) {
std::cout << "hello2" << std::endl;
} else {
std::cout << "hello3" << std::endl;
}

// This is GOOD
while (true) {
std::cout << "hello" << std::endl;
}

// This is GOOD
do {

} while (true);

Binary Operators​

Binary operators such as =, +, -, *, /, etc. should have a space on both the left and right side.

// GOOD
int c = a + b;

// BAD
int c=a+b;

Linting​

To ensure that your code is consistent, you can use cpplint.py. Cpplint is a python script which can inspect codebases for stylistic errors. It can be installed as follows:

python3 -m pip install cpplint
// Copyright [year] <Copyright Owner>

#ifndef MY_HEADER_GUARD
#define MY_HEADER_GUARD

namespace my_namespace {

class MyName {
int my_var_;

void MyFunc() {
int hi;
}
};

}

#endif

This violates the rule that the namespace is missing the namespace comment. cpplint can be executed as follows to detect this error:

cd ${GRC_TUTORIAL}/cpp/04-cpp-basic-syntax
cpplint --recursive src/cpplint_test.h

Output:

src/cpplint_test.h:16:  Namespace should be terminated with "// namespace my_namespace"  [readability/namespace] [5]
Done processing src/cpplint_test.h
Total errors found: 1

You can tune the set of errors cpplint checks for by creating a CPPLINT.cfg file.

Documentation​

Code documentation is important to improve the readability of code and to give some guidance on how to interpret the codebase. AI models, for example, can crawl well-documented codebases to help provide examples.

The most used documentation format is called Doxygen.