Files
metabuilder/dbal/cpp/docs/README.Linting.md

6.1 KiB

C++ Code Quality and Linting Guide

Overview

The DBAL C++ project uses industry-standard tools for maintaining code quality:

  • clang-tidy: Static analysis and linting
  • clang-format: Code formatting
  • cppcheck: Additional static analysis
  • Doxygen: Documentation generation

Quick Start

Run All Checks

cd dbal/cpp
./lint.sh

Apply Automatic Fixes

./lint.sh --fix

Tools

1. clang-tidy

Purpose: Static analysis, best practices enforcement, modern C++ suggestions

Configuration: .clang-tidy

Enabled Checks:

  • bugprone-* - Potential bugs
  • cert-* - CERT secure coding guidelines
  • clang-analyzer-* - Clang static analyzer
  • cppcoreguidelines-* - C++ Core Guidelines
  • google-* - Google C++ Style Guide
  • modernize-* - Modern C++ suggestions
  • performance-* - Performance improvements
  • readability-* - Code readability

Usage:

# Single file
clang-tidy src/daemon/server.cpp -p build/

# All files
find src -name "*.cpp" | xargs clang-tidy -p build/

2. clang-format

Purpose: Automatic code formatting

Configuration: .clang-format

Style: Based on Google C++ Style Guide with customizations:

  • 4-space indentation
  • 100 character line limit
  • Attach braces
  • Pointer/reference alignment: left

Usage:

# Check formatting
clang-format --dry-run --Werror src/daemon/server.cpp

# Apply formatting
clang-format -i src/daemon/server.cpp

# Format all files
find src include -name "*.cpp" -o -name "*.hpp" | xargs clang-format -i

3. cppcheck

Purpose: Additional static analysis for potential bugs

Usage:

cppcheck --enable=all \
         --suppress=missingIncludeSystem \
         --std=c++17 \
         -I include \
         src/

4. Doxygen

Purpose: Generate HTML documentation from code comments

Style: Javadoc-style comments

Example:

/**
 * @brief Brief description
 *
 * Detailed description of the function or class.
 *
 * @param param1 Description of parameter
 * @param param2 Description of parameter
 * @return Description of return value
 * @throws Error Description of when error is thrown
 *
 * @example
 * @code
 * auto result = myFunction(42, "test");
 * if (result.isOk()) {
 *     std::cout << result.value();
 * }
 * @endcode
 */
Result<int> myFunction(int param1, const std::string& param2);

Generate docs:

doxygen Doxyfile

Documentation Standards

File Headers

Every source file should have a file-level docstring:

/**
 * @file filename.cpp
 * @brief Brief description of file purpose
 *
 * Detailed description of what this file contains,
 * its role in the system, and any important notes.
 */

Class Documentation

/**
 * @class ClassName
 * @brief Brief description of class purpose
 *
 * Detailed description of the class, its responsibilities,
 * and how it should be used.
 *
 * @example
 * @code
 * ClassName obj(param1, param2);
 * obj.doSomething();
 * @endcode
 */
class ClassName {
    // ...
};

Function Documentation

/**
 * @brief Brief description of what function does
 *
 * Detailed description including algorithm details,
 * preconditions, postconditions, and side effects.
 *
 * @param param1 Description of first parameter
 * @param param2 Description of second parameter
 * @return Description of return value
 * @throws ErrorType When this error occurs
 *
 * @note Special notes or caveats
 * @warning Important warnings
 * @see Related functions or classes
 */
Result<ReturnType> functionName(Type1 param1, Type2 param2);

Member Variables

class MyClass {
private:
    int counter_;         ///< Brief description of member
    std::string name_;    ///< Brief description of member
};

Naming Conventions

Enforced by clang-tidy configuration:

  • Classes/Structs: CamelCase
  • Functions: camelCase
  • Variables: lower_case
  • Constants: UPPER_CASE
  • Member variables: lower_case_ (trailing underscore)
  • Namespaces: lower_case

Pre-commit Hooks

To automatically run linting before commits:

# Create pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
cd dbal/cpp
./lint.sh
if [ $? -ne 0 ]; then
    echo "Linting failed. Fix issues or use git commit --no-verify to skip."
    exit 1
fi
EOF

chmod +x .git/hooks/pre-commit

IDE Integration

VSCode

Install extensions:

  • C/C++ (Microsoft)
  • clangd
  • Clang-Format

Settings (.vscode/settings.json):

{
    "clang-format.executable": "/usr/bin/clang-format",
    "clang-format.style": "file",
    "editor.formatOnSave": true,
    "C_Cpp.codeAnalysis.clangTidy.enabled": true,
    "C_Cpp.codeAnalysis.clangTidy.path": "/usr/bin/clang-tidy"
}

CLion

Settings → Editor → Code Style → C/C++:

  • Scheme: Set from file (.clang-format)

Settings → Editor → Inspections → C/C++:

  • Enable "Clang-Tidy"
  • Configuration file: .clang-tidy

Continuous Integration

Add to GitHub Actions workflow:

- name: Lint C++ Code
  run: |
    cd dbal/cpp
    ./lint.sh

Common Issues and Fixes

Issue: "Use of old-style cast"

// Bad
int x = (int)value;

// Good
int x = static_cast<int>(value);

Issue: "Variable never read"

// Bad
int unused = 42;

// Good
[[maybe_unused]] int for_future_use = 42;

Issue: "Missing const"

// Bad
std::string getName() { return name_; }

// Good
std::string getName() const { return name_; }

Issue: "Pass by value instead of const reference"

// Bad
void setName(std::string name) { name_ = name; }

// Good
void setName(const std::string& name) { name_ = name; }

Metrics

The lint script reports:

  • Formatting violations
  • Static analysis warnings
  • TODO/FIXME comments count
  • Long functions (>100 lines)

Aim for zero warnings before committing.

Resources