Naming Conventions
General Naming Rules
[rule] CPP-001
All names should be in EnglishThe single exception to this rule is if there is a necessity to use names originating from non-English documentation.
[rule] CPP-002
Use intention-revealing namesThe name of a variable, type or function should intuitively imply why it exists and what it does. Spending a considerable amount of time finding good names saves future time for everyone (including yourself) wanting to read and understand the code.
[rule] CPP-003
As long as necessary - as short as possibleWhen choosing names, aim for improving readability of the code. Names should be descriptive, but at the same time as short as possible.
Adding meaningful context can help to better/faster understand your code. For example a variable named
address
is probably considered rather ambiguous. Adding more context to its name, e.g.ipAddress
orpostalAddress
makes it much easier to reason about this variable without even knowing which software module it is in. On the other hand, overly complicated names and gratuitous context (e.g.BspEthernetControllerInstanceManager
) are hard to read and remember, and only increase the mental overhead in understanding the code. Also, keep in mind that type of the variable, the usage of well-known idioms (like naming a loop-counter variablei
), etc. also contribute to the context and help the reader.
Type Names
[rule] CPP-004
Names representing types must be written in UpperCamelCase.
using TcpipEventManager = ::os::EventManager<task_tcpip>;
Any exceptions to this rule need to have a reasonable justification and in that
case should be applied consistently within a module (e.g. estd
types use
snake_case notation in order to match with their STL counterpart). In general
those exceptions should be rare!
Variable Names
[rule] CPP-005
Variable names must be written in lowerCamelCase and should not carry any
prefix (except Member Variable Names)
Particle higgsBoson;
Warning
We do not use Hungarian Notation.
Constant Names
[rule] CPP-006
Constants with static storage duration, e.g. global const
, constexpr
or
local static const
, are named using ALL_CAPITAL_LETTERS
interleaved with underscores.
[rule] CPP-007
All other constants, e.g. local non-static, follow the usual Variable Names
convention.
const int SOME_GLOBAL_CONSTANT = 1337;
class Life
{
public:
static const MEANING = 42;
bool halfTheTruth(const int value)
{
const int half = value / 2;
return half;
}
};
Function Names
[rule] CPP-008
Choose expressive names for (member-)functions and format them using
lowerCamelCase.
Usually function names contain verbs reflecting what they are actually doing.
Thereby, choose one word per concept, e.g. do not mix fetch
, retrieve
and get
within the same context.
The type name of the object is implicit, and should be avoided in a method name.
Try to be precise without repeating yourself. For example if you provide a
function to send a CanFrame
just call it send
instead of
sendCanFrame
. The function signature already tells the user that this
function sends a CanFrame
.
// good
class CanTransceiver
{
public:
ErrorCode send(const CanFrame& frame);
static bool addGlobalListener(ICanFrameListener& listener);
};
// bad
class CanTransceiver
{
public:
ErrorCode SendFrame(const CanFrame& frame);
static bool AddGlobalListener(ICanFrameListener& listener);
};
Classes
Class Names
[rule] CPP-009
Class names are written in UpperCamelCase.
Also abbreviations like
CAN
are camel cased toCan
.
[rule] CPP-010
Interface names start prefixed with a capital I
.
[rule] CPP-011
Names of abstract classes are not treated specially any
more, we used to prefix them with Abstract
.
[rule] CPP-012
In unit tests, when writing a mock, the class name is usually
postfixed with Mock.
// good
class CanTransceiver; // regular class
class CanTransceiverMock; // according mock class
class ITransportMessageProvider; // interface
// bad
class CANTransceiver; // abbreviation not camel case
class filteredLinFrameListener; // wrong capitalization
class AbstractDiagJob; // Abstract prefix is deprecated
See also
Global naming conventions in Naming Conventions
Member Variable Names
[rule] CPP-013
Member variables of a class
, struct
or union
shall be prefixed with
an _
(underscore) in order to distinguish them easily from local variables.
[rule] CPP-014
If a struct
or union
is a POD, i.e. all members are public and it
does not provide any functions, you can omit the prefix.
Note
In legacy code you will find the prefix f
a lot but also m
or
_
. You can keep these prefixes as long as you stay consistent within
your legacy module. [rule] CPP-015
Never mix styles!
class CanTransceiver // good
{
::estd::forward_list<ICanFrameListener> _listeners;
};
struct Result // good
{
::bsp::ErrorCode status;
uint16_t value;
};
class CanTransceiver // bad, no member prefix
{
::estd::forward_list<ICanFrameListener> listeners;
};
struct Result // bad, suffix and mixed style
{
::bsp::ErrorCode Status;
uint16_t value_;
};
Namespace Names
[rule] CPP-016
Names representing namespaces should be all lowercase.
model::analyzer
io::iomanager
common::math::geometry
File Names
[rule] CPP-017
Files containing classes should only contain a single class. The header and
source file are named according to that class in PascalCase, e.g. MyClass.h
and
MyClass.cpp
.
[rule] CPP-018
The extension for C++ source files is .cpp
, the extension for C
source files is .c
, the extension for assembly files is .s
.
Header files have the extension .h
no matter which content.
[rule] CPP-022
If a file contains no class but only free function declarations it should
have a meaningful name in camelCase, e.g. routingAddons.h
.
Module Names
[rule] CPP-023
Module names must be written in lowerCamelCase.
// good
doip
cdc2Crypto
osUtils
noInitRam
// bad
cpp2can
state_machine
mymodule
YourModule
Special Cases
Abbreviations in Names
[rule] CPP-019
Abbreviations in code should be written to match the appropriate contextual
casing style to maintain style consistency and code readability.
class CANReader // bad, not using UpperCamelCase
{
uint32_t const can_bus = 10; // bad, not using UPPER_SNAKE_CASE
void initCAN(); // bad, not using lowerCamelCase
};
class CanReader // good
{
uint32_t const CAN_BUS = 10; // good
void initCan(); // good
};
Boolean Variables and Functions
[rule] CPP-020
Boolean variable and function names shall start withis
orhas
. Likewise, a function prefixed withhas
oris
shall return a boolean.bool isTerminated = connection.terminate(); // good bool terminated = connection.terminate(); // bad bool hasValidPayload() const { ... } // good bool checkPayload() { ... } // bad
[rule] CPP-021
Negated boolean variable names must be avoided.The problem arises when such a name is used in conjunction with the logical negation operator as this results in a double negative. It is not immediately apparent what
!isNotFound
means.Try to find short and precise names for the variables or functions. It often depends on the context, e.g. a variable within a Connection class can be named
isTerminated
, but in a broader context it might be good to name itisConnectionTerminated
.Generally, avoid misunderstandings about the meaning. Does it indicate that an error happened? Or that everything is good to go? If it’s still unclear, document the variable or return value.
An alternative is using an enum.
Pros:
more expressive
can be extended
Cons:
needs more typing
extending an enum can be dangerous if not handled properly by the callers of the function
might need conversion if propagated to higher levels
Other rarely used types are bitfields and ranges. For return values of functions it is worth to look at
::estd::result
class which combines data and error status in one object.In most cases using a boolean is the best choice to keep it simple.
Plural Forms Should Be Used on Names Representing a Collection of Objects
Enhances readability since the name gives the user an immediate clue of the type of the variable and the operations that can be performed on its elements.
using ReceiverList = ::estd::forward_list<Receiver>;
vector<Point> points;
int values[];
Be careful not to lie with names, i.e. do not name a collection of Point
objects pointList
unless it’s actually a List
-type.