Analysis & Formatting
Updated 2025-01-01T00:00:00.000ZCppcheck — Static Analysis
Cppcheck for C++ — running checks, suppressing false positives, CMake integration, CI setup, and comparison with clang-tidy.
TL;DR
Cppcheck is a static analysis tool that finds bugs (null pointer dereference, out-of-bounds, memory leaks, undefined behavior) without compiling. Complements compiler warnings and clang-tidy — runs on code that doesn't compile cleanly.
Installation
bash
# Ubuntu/Debian
sudo apt install cppcheck
# macOS
brew install cppcheck
# Windows (Chocolatey)
choco install cppcheck
# Build from source
git clone https://github.com/danmar/cppcheck.git
cmake -B build && cmake --build buildBasic Usage
bash
# Check a single file
cppcheck main.cpp
# Check a directory recursively
cppcheck src/
# Show all messages (not just errors)
cppcheck --enable=all src/
# Specific checks
cppcheck --enable=warning,performance,portability src/
# C++17 standard
cppcheck --std=c++17 src/
# Define macros / includes
cppcheck -DDEBUG -I include/ src/Check Categories
cpp
error - definite bugs (null pointer, OOB, use-after-free)
warning - possibly buggy code (uninitialized variables, etc.)
style - code style issues (unused variables, redundant code)
performance - performance suggestions (unnecessary copies)
portability - non-portable constructs
information - informational messages
all - enable everything above
unusedFunction- functions never called (whole-project scan)Output Format
bash
# Default output
cppcheck src/
# [src/main.cpp:42]: (error) Null pointer dereference: ptr
# XML output for CI integration
cppcheck --xml --xml-version=2 src/ 2> report.xml
# Template format
cppcheck --template="{file}:{line}: {severity}: {message} [{id}]" src/Suppressing False Positives
cpp
// Suppress inline (preferred for one-off)
// cppcheck-suppress nullPointer
ptr->method();
// Suppress with reason
// cppcheck-suppress uninitvar ; reason: initialized in init() before use
int x;
// Suppress by ID in suppression file
// cppcheck-suppress arrayIndexOutOfBounds
arr[i] = val;bash
# Suppression file (suppressions.txt)
# nullPointer:src/legacy.cpp:42
# uninitvar
cppcheck --suppressions-list=suppressions.txt src/CMake Integration
cmake
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
set(CMAKE_CXX_CPPCHECK
${CPPCHECK}
--std=c++17
--enable=warning,performance,portability
--suppress=missingIncludeSystem
--error-exitcode=1
--inline-suppr
)
endif()CI Example (GitHub Actions)
yaml
- name: Run cppcheck
run: |
cppcheck \
--std=c++17 \
--enable=all \
--suppress=missingIncludeSystem \
--error-exitcode=1 \
--xml --xml-version=2 \
src/ 2> cppcheck-report.xml
- name: Upload cppcheck report
if: failure()
uses: actions/upload-artifact@v3
with:
name: cppcheck-report
path: cppcheck-report.xmlCppcheck vs clang-tidy
| cppcheck | clang-tidy | |
|---|---|---|
| Requires compilation | No | Yes (compile_commands.json) |
| Bug finding | Strong | Strong |
| Code modernization | No | Yes (modernize-* checks) |
| Performance checks | Basic | Strong |
| False positive rate | Low | Medium |
| Speed | Fast | Slower |
| Use together? | Yes — complementary | Yes |
Use both: cppcheck for quick scans and CI gates, clang-tidy for modernization and deeper analysis.
Edit on GitHubUpdated 2025-01-01T00:00:00.000Z