My personal projects follow these guidelines. They are based on personal preferences.
C++ projects target C++20.
When developing a library, the cpp-library tool decides on the project structure.
The following structure is garantueed:
- include/PROJECT/ contains the header files for distribution.
- lib/CONFIG/ contains the compiled static and or shared libraries.
- src/ containing all source files (hpp and cpp) for the project.
- cpp-library.json contains information about the library.
For application projects, there is no fixed project structure yet.
Types are named in
PascalCase
.
Note that this applies to classes, structs, enums, aliases, typedefs and concepts!
Functions are named in
camelCase
.
Function names should be structured in one of the following ways:
- verb, e.g. sort( )
- verb + Object, e.g. constructEntity( )
- verb + Adjective + Object, e.g. calcLegalMoves( )
Functions of "constant character" are named in PascalCase
.
They don't start with a verb.
For example:
int TypeSize(DType type) {
switch (type) {
case DType::INT:
return 4;
case DType::FLOAT:
return 4;
case DType::DOUBLE:
return 8;
default:
return -1;
}
}
Variables are named in
camelCase
.
Depending on the storage duration, the following prefixes are added:
m_
for member variables, e.g. m_elementCounts_
for static variables, e.g. s_rootPathg_
for global variables, e.g. g_projectConfig
Constants are named in
UPPER_CASE
.
A variable is considered a constant if declared const or constexpr and whose value is fixed for the duration of the program.
Note that the following is not considered a constant:
Vec3 normalize(Vec3 vector) {
const double length = vector.length();
return vector / length;
}
Namespaces are named in
PascalCase
.
Enumerators are named in
UPPER_CASE
.
For example:
enum Color {
RED, GREEN, BLUE
};
Macros are named in
UPPER_CASE
.
Use
// ...
insted of/* ... */
.
Structural comments are used to emphasize the structure of a file. They carry no additional information about the code semantics.
Type declarations are emphasized by adding comments with their name in front.
For example:
// Point
struct Point {
int x, y;
}
Funtion definitions are emphasized by adding comments with their name in front.
For example:
// isEven
bool isEven(int num) {
return !bool(num % 2);
}
Overloaded function declarations are emphasized once.
For example:
// isPrime
bool isPrime(int num);
bool isPrime(unsigned int num);
Functions can be grouped together by adding a comment with the group logic in front (in lowercase).
For example:
// arithmetic
Vec3 operator+(Vec3 x, Vec3 y);
Vec3 operator-(Vec3 x, Vec3 y);
Vec3 operator*(Vec3 x, double scalar);
Vec3 operator/(Vec3 x, double scalar);
Constructors and destructors are emphasized with
// constructor
and// destructor
instead of their type names.
For example:
// Point
class Point {
// constructor
Point(int x, int y)
: x(x), y(y) {}
// member
int x, y;
};
Nested emphases are prefixed with a
::
.
For example:
// arithmetic
// :: operator+
Vec2 operator+(Vec2 x, Vec2 y);
Vec3 operator+(Vec3 x, Vec3 y);
// :: operator-
Vec2 operator-(Vec2 x, Vec3 2);
Vec3 operator-(Vec3 x, Vec3 y);
Note that this doesn't apply when the emphases occur in different scopes.
Code blocks in function definitions can be grouped together into logical parts (in lowercase).
For example:
// castle privileges
// :: white king moves
if (origin == toSquare("e1")) {
castle[Castle::WHITE_KINGSIDE] = false;
castle[Castle::WHITE_QUEENSIDE] = false;
}
// :: black king moves
else if (origin == toSquare("e8")) {
castle[Castle::BLACK_KINGSIDE] = false;
castle[Castle::BLACK_QUEENSIDE] = false;
}
// :: white kingside rook moves
else if (origin == toSquare("h1")) {
castle[Castle::WHITE_KINGSIDE] = false;
}
// :: white queenside rook moves
else if (origin == toSquare("a1")) {
castle[Castle::WHITE_QUEENSIDE] = false;
}
// :: black kingside rook moves
else if (origin == toSquare("h8")) {
castle[Castle::BLACK_KINGSIDE] = false;
}
// :: black queenside rook moves
else if (origin == toSquare("a8")) {
castle[Castle::BLACK_QUEENSIDE] = false;
}
Indent with spaces. Each indentation level contains 4 spaces.
Braces are positioned using the
K&R
style.
For example:
int main() {
return EXIT_SUCCESS;
}