[2026] Static Analysis in C++: Enforce Quality with Clang-Tidy & Cppcheck [#41-1]

[2026] Static Analysis in C++: Enforce Quality with Clang-Tidy & Cppcheck [#41-1]

이 글의 핵심

Integrate clang-tidy (.clang-tidy, compile_commands) and Cppcheck into editors and CI. Fix use-after-move, leaks, and style drift before runtime. SEO: clang-tidy, cppcheck, static analysis, CI.

Introduction: catch bugs before you run

Static analysis inspects source without executing it. Clang-Tidy provides hundreds of checks for modern C++, performance, and bugprone patterns. Cppcheck is compiler-independent and strong on memory, null derefs, and bounds issues. Together they complement each other. Covers: scenarios, .clang-tidy, compile_commands.json, representative checks, --fix, Cppcheck flags/suppressions, CI workflows, incremental analysis, adoption strategy.

Table of contents

  1. Why static analysis
  2. Clang-Tidy
  3. Cppcheck
  4. Complete demo project
  5. Common errors
  6. CI integration
  7. Production patterns
  8. Summary

1. Why static analysis

Production crashes from null derefs, use-after-move, range-for copies, magic numbers—many are detectable statically when configured. Real-world impact: a single use-after-move bug in production can crash servers under load, but clang-tidy catches it at commit time with bugprone-use-after-move. Common scenarios:

  • Null pointer dereference: Cppcheck flags *ptr without null checks
  • Use-after-move: Clang-tidy detects accessing moved-from objects
  • Performance: performance-for-range-copy finds expensive copies in range loops
  • Style drift: readability-identifier-naming enforces team conventions 아래 코드는 mermaid를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
// 실행 예제
flowchart LR
    A[Compile] --> B[Clang-Tidy]
    A --> C[Cppcheck]
    B --> D[Gate merge]
    C --> D

Team benefit: catching issues before code review saves 10-30 minutes per PR and reduces back-and-forth.

2. Clang-Tidy

Clang-Tidy is LLVM’s linter with 400+ checks. It requires compile_commands.json to understand your build flags and includes. Setup: create .clang-tidy in your project root: 아래 코드는 yaml를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 실행 예제
Checks: 'bugprone-*,modernize-use-nullptr,performance-for-range-copy,readability-identifier-naming'
WarningsAsErrors: '
HeaderFilterRegex: '.*'
CheckOptions:
  - key: readability-identifier-naming.ClassCase
    value: CamelCase

Generate compile_commands.json with CMake:

cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
clang-tidy -p build src/*.cpp

Auto-fix: --fix applies safe fixes, but always review with git diff and run tests. Example: modernize-use-nullptr converts NULL to nullptr automatically. Editor integration: VS Code C++ extension and CLion read .clang-tidy automatically, showing warnings inline as you type.

3. Cppcheck

Cppcheck is compiler-independent and excels at detecting memory leaks, null derefs, and out-of-bounds access. Unlike clang-tidy, it doesn’t need compile_commands.json. Basic usage:

cppcheck --enable=all --suppress=missingIncludeSystem -I include --error-exitcode=1 -j8 src/

Flags explained:

  • --enable=all: all checks (warning, style, performance, portability)
  • --suppress=missingIncludeSystem: ignore system headers
  • -I include: add include paths
  • --error-exitcode=1: fail CI on errors
  • -j8: parallel analysis (8 threads) Suppression: add // cppcheck-suppress nullPointer above false positives, or use --suppressions-list=suppressions.txt for project-wide rules. Complementary: Cppcheck finds issues clang-tidy misses (e.g., if (x = 5) assignment in condition) and vice versa. Run both for comprehensive coverage.

4. Demo project

Check in CMakeLists.txt, a sample .clang-tidy, and run-static-analysis.sh alongside your project for reproducible CI runs.

5. Common errors

  • Missing compile_commands.json → configure CMake with export.
  • Too many diagnostics on legacy code → enable gradually, NOLINT sparingly, exclude third_party via HeaderFilterRegex.

6. CI integration

GitHub Actions example: 다음은 yaml를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

name: Static Analysis
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install tools
        run: sudo apt-get install -y clang-tidy cppcheck
      - name: CMake
        run: cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
      - name: Clang-Tidy
        run: clang-tidy -p build src/*.cpp
      - name: Cppcheck
        run: cppcheck --enable=all --error-exitcode=1 src/

Optimization: for large repos, run only on changed files using git diff --name-only origin/main...HEAD | grep '\.cpp$' to filter files. This reduces CI time from minutes to seconds. Fail-fast: set --warnings-as-errors in clang-tidy or --error-exitcode=1 in cppcheck to block merges with issues.

7. Production patterns

Pre-commit hooks, clangd in-editor, split warnings-as-errors by check category.

8. Summary

ToolFocus
Clang-TidyModern C++, performance, many autofixes
CppcheckMemory, control flow without full compilation
Next: ASan/TSan (#41-2)
Previous: Docker for C++ (#40-3)

Keywords

clang-tidy, cppcheck, static analysis, compile_commands.json, CI quality

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3