C Code Style Guide

I follow this guide to ensure that all C code I write for Fossil Logic is readable, maintainable, and consistent, supporting collaboration and long-term project stability.

1. General Principles

  • I write code that is clear and self-explanatory.
  • I prioritize readability over cleverness or brevity.
  • I document my reasoning when code is non-obvious.

2. File Structure

  • I include a clear header comment at the top of each file with its purpose, author, and creation date.
  • I organize #include directives logically:
    1. Corresponding header for the file.
    2. Standard library headers.
    3. Project headers.
  • I separate logical sections in the file with comment blocks.

3. Naming Conventions

  • I use snake_case for variables and functions.
  • I use UPPERCASE_WITH_UNDERSCORES for macros and constants.
  • I give meaningful names that describe the purpose, avoiding abbreviations unless widely understood.

4. Indentation and Formatting

  • I use 4 spaces per indentation level; tabs are avoided.
  • I place opening braces { on the same line as the statement or function.
  • I maintain consistent spacing around operators and after commas.
  • I break long lines at logical points, typically 80–100 characters per line.

5. Functions

  • I keep functions short and focused; ideally under 50 lines.
  • I declare function prototypes in headers and define functions in implementation files.
  • I group related functions together and use clear section comments.

6. Control Structures

  • I always use braces {} for if, else, for, and while blocks, even for single statements.
  • I maintain consistent indentation inside control blocks.
  • I use early returns to reduce nested blocks and improve readability.

7. Pointers and Memory Management

  • I use NULL for uninitialized pointers and check for null before dereferencing.
  • I clearly pair malloc()/calloc() with free() and document ownership rules.
  • I minimize pointer arithmetic and prefer clear, explicit operations.

8. Comments and Documentation

  • I write comments that explain why, not what—code should be self-explanatory.
  • I use block comments for sections and inline comments sparingly for complex logic.
  • I maintain documentation in headers for public APIs, including parameter descriptions, return values, and error handling.

9. Error Handling

  • I consistently check return values and propagate errors where appropriate.
  • I define error codes or enums rather than using magic numbers.
  • I document failure cases clearly.

10. Preprocessor and Macros

  • I avoid unnecessary macros; prefer const or inline functions.
  • I guard headers with #ifndef / #define / #endif.
  • I keep macro names unique and descriptive to avoid conflicts.

11. Testing and Debugging

  • I write testable code with modular functions.
  • I include assertions or logging for critical assumptions.
  • I remove temporary debug code before committing, leaving optional debug flags if necessary.

12. Version Control Practices

  • I ensure code compiles cleanly and passes tests before committing.
  • I write descriptive commit messages that explain what and why.
  • I follow project coding conventions consistently to reduce merge conflicts.

What are your feelings

Updated on August 31, 2025