I follow this guide to ensure that all C++ code I write for Fossil Logic is readable, maintainable, and consistent, enabling collaboration and long-term stability.
1. General Principles
- I prioritize clarity and simplicity over cleverness.
- I write code that is self-explanatory wherever possible.
- I document my reasoning for non-obvious code or design choices.
2. File Structure
- I include a header comment at the top of each file explaining its purpose, author, and creation date.
- I organize
#includedirectives in the following order:- Corresponding header.
- Standard library headers.
- Third-party headers.
- Project headers.
- I separate logical sections in files with clear comment blocks.
3. Naming Conventions
- I use snake_case for variables and functions.
- I use PascalCase for classes, structs, and namespaces.
- I use UPPERCASE_WITH_UNDERSCORES for macros and constants.
- Names are descriptive and avoid unnecessary abbreviations.
4. Indentation and Formatting
- I use 4 spaces per indentation level; tabs are avoided.
- I place opening braces
{on the same line for functions and control structures. - I keep lines under 100 characters and break long expressions at logical points.
- I maintain consistent spacing around operators, commas, and keywords.
5. Classes and Structs
- I keep classes focused and small; each class should have a clear responsibility.
- I declare member functions in headers and define them in implementation files.
- I group public, protected, and private sections in that order.
- I prefer explicit constructors, deleted copy/move operations when necessary, and defaulted special functions for clarity.
6. Functions
- I keep functions short, ideally under 50 lines.
- I prefer passing parameters by const reference when possible.
- I use early returns to reduce nesting and improve readability.
- I document parameters, return values, and exceptions for all public APIs.
7. Memory Management
- I prefer RAII, smart pointers (
std::unique_ptr,std::shared_ptr), and standard containers over raw pointers. - I clearly define ownership semantics and avoid memory leaks.
- I minimize manual memory management and avoid unnecessary pointer arithmetic.
8. Control Structures
- I always use braces
{}forif,else,for,while, andswitchblocks, even for single statements. - I maintain consistent indentation and alignment.
- I prefer range-based
forloops when iterating over containers.
9. Templates and Generics
- I use templates sparingly and clearly document expected types.
- I prefer
typenameoverclassfor template parameters for clarity. - I avoid overly complex template metaprogramming unless necessary.
10. Error Handling
- I use exceptions for recoverable errors and document what exceptions may be thrown.
- I avoid silent failure; all error paths should be handled or logged.
- I define error enums or classes rather than relying on magic numbers.
11. Comments and Documentation
- I write comments that explain why, not what; the code should be self-explanatory.
- I use block comments for sections and inline comments sparingly for complex logic.
- I maintain Doxygen-style comments for public APIs.
12. Testing and Debugging
- I write modular, testable code.
- I include assertions or logging for critical assumptions.
- I remove temporary debug code before committing, leaving optional debug flags if needed.
13. Version Control Practices
- I ensure code compiles cleanly and passes tests before committing.
- I write descriptive commit messages explaining what and why.
- I follow project conventions consistently to reduce merge conflicts.