ErbslandDEV C++ Code Style Summary
This guide defines the basic C++ style conventions used across ErbslandDEV codebases. It is focused on clarity, maintainability, and practical modern C++ usage.
Naming Conventions
Classes: PascalCase (e.g.,
Controller,TestClassBase)Methods and Functions: camelCase (e.g.,
addTestClass,parseCommandLine)Member Variables:
_underscorePrefix(e.g.,_console,_testClasses)Global Constants:
cExampleif not in dedicated namespace.Namespaces: all lowercase with nested structure (e.g.,
erbsland::unittest)Preprocessor Macros: all uppercase
EXAMPLE
File Organization
Header Guards: Use
#pragma onceInclude Order (separate blocks with empty lines): 1. Corresponding header (if in
.cpp) — followed by two empty lines 2. Local includes:#include "Example.hpp"3. Local subdirectory includes:#include "sub/sub/Example.hpp"4. Local relative includes:#include "../../Example.hpp"5. Project libraries:#include <erbsland/core/String.hpp>6. Standard library headers:#include <vector>7. Two empty lines after the include blockFile Extensions: Use
.hppfor headers,.cppfor implementationsFile Scope: Aim for one class per file, with matching name
Maximum File Length: Try to keep files under 500 lines
Formatting
Indentation: 4 spaces, no tabs
Line Length: Target a maximum of 120 characters per line
Braces: Opening brace stays on the same line
Spacing and Separation: - Use empty lines to separate logical blocks - One empty line between function definitions if they span >3 lines or have documentation - Two empty lines around
struct,class, orenumdefinitions - Two empty lines around function implementations in.cppfiles
Constants & Literals
Prefer
constexprorconstwhere applicableNever use macros for constants
Move mechanic requires mutable instances!
Modern C++ Usage
Use C++20 syntax
Always use trailing return types for all non-void functions:
auto create() -> std::string;Use
autowhen the type is obvious or improves readabilityUse structured binding
const auto &[a, b] =Use
[[nodiscard]]andnoexceptwhere applicableUse
overridefor overwritten/implemented functionsUse
finalfor final classesUse designated initialization if it improves the readability of the code
Use
std::unique_ptr/std::shared_ptrinstead of raw pointersPrefer range-based
forloopsUse
std::formatandstd::chronofor formatted output and timingPrefer
std::rangesandstd::viewsfor expressive algorithms
Quality and Safety First
Avoid manual memory management and raw pointers
Trust the compiler to optimize; prioritize clarity over micro-optimization
Perform bounds and range checks
Write unit tests for all modules and key functions
Ensure good test coverage and fail clearly when things go wrong
A crash is better than silent failure or undefined behavior
Comments
Public API Docs: Use
///and Doxygen@-syntaxInline Comments: Use
//for short clarifying notesBlock Comments: Avoid
/* ... */unless necessarySpecial Doxygen Tags: -
@tested: Indicates this is covered by a unit test (name or path to the tests) -@notest: Explains why a unit test is not applicable -@needtest: Flags untested functionality -@wip: This part is work in progress—talk to the author before modifying