Skip to content

fburgerdev/cpp-guidelines

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

CPP-Guidelines

My personal projects follow these guidelines. They are based on personal preferences.

Table of Contents

  1. General Notes
  2. Project Structure
  3. Naming Convetions
  4. Comments
  5. Formatting

1. General Notes

C++ projects target C++20.

2. Project Structure

Library

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.

Application

For application projects, there is no fixed project structure yet.

3. Naming Conventions

Types

Types are named in PascalCase.

Note that this applies to classes, structs, enums, aliases, typedefs and concepts!

Functions

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

Variables are named in camelCase.

Depending on the storage duration, the following prefixes are added:

  • m_ for member variables, e.g. m_elementCount
  • s_ for static variables, e.g. s_rootPath
  • g_ for global variables, e.g. g_projectConfig

Constants

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

Namespaces are named in PascalCase.

Enumerators

Enumerators are named in UPPER_CASE.

For example:

enum Color {
    RED, GREEN, BLUE
};

Macros

Macros are named in UPPER_CASE.

4. Comments

Use // ... insted of /* ... */.

Structural Comments

Structural comments are used to emphasize the structure of a file. They carry no additional information about the code semantics.

Types

Type declarations are emphasized by adding comments with their name in front.

For example:

// Point
struct Point {
    int x, y;
}

Functions

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;
}

5. Formatting

Indentation

Indent with spaces. Each indentation level contains 4 spaces.

Braces are positioned using the K&R style.

For example:

int main() {
    return EXIT_SUCCESS;
}

About

C++ guidelines for personal projects

Topics

Resources

Stars

Watchers

Forks