C++ Intermediate · Lesson 27 of 27
clang-tidy and static analysis
Finding bugs without running the code, and using compile_commands.json.
Estimated time · 45–75 min
Learning goals
What you will understand
- Explain clang-tidy and static analysis in your own words
- Use it in a small robotics example
- Verify the result instead of assuming it worked
Understand the idea first
The mental model
Static analysis reads your code and reports likely bugs, style problems and outdated constructs without executing it. clang-tidy has hundreds of checks; useful groups are bugprone-*, performance-*, modernize-* and readability-*. Enable CMAKE_EXPORT_COMPILE_COMMANDS so the tool sees the same flags as the compiler.
Treat findings as questions: understand each one before fixing it, and never silence a check just to make the report green. Add clang-tidy and clang-format to your CI job so problems are caught before merging. ROS 2 also provides ament_lint for the same purpose.
Guided lesson
Work through these steps
- 1.
Read the clang-tidy and static analysis example and identify what each line owns or changes.
- 2.
Create a small source file, compile with -std=c++17 and warnings enabled, and run it.
- 3.
Change one input, predict the result before running, then compare the output.
- 4.
Record one compiler or runtime error and explain the correction in your own words.
Worked example
Read it before you run it
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# Configure and write build/compile_commands.json, the list of exact compiler commands.
clang-tidy -p build src/main.cpp
# Analyse one file using the compile commands in build/.
clang-tidy -p build --checks='bugprone-*,performance-*,modernize-*' src/main.cpp
# Run only selected groups of checks.
clang-tidy -p build --fix src/main.cpp
# Apply the automatic fixes (commit first so you can review the diff).
clang-format -i src/main.cpp
# Reformat the file in place using the project style.
cppcheck --enable=warning,style --std=c++17 src
# A second, independent analyser for a different set of findings.What the example is doing
- 1.Read declarations from right to left: identify each value's type, name, and initial value.
- 2.Follow the data through each expression before considering syntax shortcuts.
- 3.Compile with warnings enabled; a clean build is part of the result, not an optional polish step.
Watch it run · Build and run
See what this code does
The terminal types this lesson's practice solution and runs it. The scene shows the kind of robot behaviour that code drives. It plays by itself and loops.
Demo for clang-tidy and static analysis. Expected result: 6
Practice code
Now type it yourself
Copy the starter into practice.cpp and replace every TODO with your own code. Build and run it: g++ -std=c++17 -Wall -Wextra -Wpedantic practice.cpp -o practice -pthread && ./practice
// Run: clang-tidy -p build --checks='modernize-*,bugprone-*' tidy.cpp
#include <iostream>
#include <vector>
int main() {
// TODO: use nullptr instead of NULL and a range-based for loop with const auto& (modernize checks)
(void)unused;
std::cout << sum << '\n';
return 0;
}Expected output
6Stuck? Show the full solution (try it yourself first)
// Run: clang-tidy -p build --checks='modernize-*,bugprone-*' tidy.cpp
#include <iostream>
#include <vector>
int main() {
const int* unused = nullptr;
std::vector<int> values{1, 2, 3};
int sum = 0;
for (const auto& v : values) sum += v;
(void)unused;
std::cout << sum << '\n';
return 0;
}Expected result
How you know it worked
- After adding the shown fragment to the guided exercise with its listed headers and surrounding program, the finished program builds with -Wall -Wextra -Wpedantic.
- Changing the stated input produces the result you predicted.
Practical exercise
Apply the lesson
Run clang-tidy with bugprone-*, performance-* and modernize-* on a program you wrote in Phase 3. Fix at least three findings by hand, explain each one in a note, and decide whether any should be ignored.
Before you continue
- The program builds with -std=c++17 and no warnings
- You can explain the key rule without reading the example
- The normal and edge cases both have recorded results
If something goes wrong
Start at the first error. Check spelling, required #include lines, and whether the declaration appears before use.
Print the inputs and intermediate values, then check conversions, units, and collection order.