Clang-Tidy 是基于 Clang 的可扩展 C++ 静态分析工具,能发现潜在 bug、风格违规、性能隐患及不符合现代 C++ 标准的写法,如裸指针所有权混乱或忽略返回值。

Clang-Tidy 是什么,它能帮你发现哪些问题
Clang-Tidy 不是编译器,而是一个基于 Clang 的 C++ 静态分析工具,专为可扩展的代码检查设计。它能识别潜在的 bug、风格违规(比如命名不一致)、性能隐患(如冗余拷贝)、以及不符合现代 C++ 标准(如 modernize-use-auto)的写法。它不替代编译器报错,但能提前暴露编译器不会警告的问题——比如 cppcoreguidelines-owning-memory 检查裸指针所有权混乱,或 bugprone-unused-return-value 提醒你漏了 std::regex_match 的返回值检查。
如何让 Clang-Tidy 识别你的项目结构(CMake + compile_commands.json)
Clang-Tidy 需要知道每个源文件的完整编译命令(含宏定义、头文件路径、C++ 标准等),否则会误报“未声明的标识符”或跳过模板实例化检查。最可靠的方式是生成 compile_commands.json:
- 用 CMake 时,在配置阶段加
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON,例如:cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_STANDARD=17
- 确保构建目录下生成了
build/compile_commands.json;如果项目用 Ninja 或 Make,该文件必须存在且路径正确 - 运行 Clang-Tidy 时,必须通过
-p参数指定该路径,否则它默认按系统头路径解析,几乎必然失败
常见错误:直接在源码根目录执行 clang-tidy *.cpp —— 这样没有编译上下文,#include "my_header.h" 会报找不到,所有依赖模板的检查(如 cppcoreguidelines-pro-bounds-array-to-pointer-decay)也会失效。
怎么启用和禁用具体检查项(.clang-tidy 配置文件)
靠命令行传一堆 --checks 很难维护。推荐用项目根目录下的 .clang-tidy 文件统一管理:
立即学习“C++免费学习笔记(深入)”;
Checks: '-*,cppcoreguidelines-*,modernize-*,performance-*,bugprone-*,misc-*'
WarningsAsErrors: ['*']
HeaderFilterRegex: '^(src|include)/'
CheckOptions:
- key: modernize-use-auto.MinTypeNameLength
value: '5'
- key: readability-identifier-naming.VariableNameStyle
value: lower_case说明:
-
-*先禁用全部检查,再显式启用需要的类别,避免继承 clang-tidy 默认启用的过时规则 -
WarningsAsErrors把所有检查结果当 error 处理(CI 中可配合--quiet和退出码判断) -
HeaderFilterRegex控制只检查匹配路径的头文件,避免对第三方库(如/usr/include)误报 -
CheckOptions调整具体规则行为,比如modernize-use-auto默认只对类型名长度 ≥ 3 的变量触发,这里改成 ≥ 5
注意:.clang-tidy 文件必须 UTF-8 编码且无 BOM,Windows 上用记事本保存易出错,建议用 VS Code 或 Vim。
实际运行与集成到开发流程(命令与 CI 示例)
本地快速扫描单个文件:
clang-tidy -p build/ src/foo.cpp --fix --header-filter='^(src|include)/'
关键参数说明:
-
--fix自动修复支持的检查(如添加override、替换auto),但不会改逻辑,也不保证 100% 安全,务必配合 git diff 查看 -
--header-filter和.clang-tidy中的HeaderFilterRegex作用一致,命令行优先级更高 - 想只看某类问题?用
--checks='-*,modernize-*'临时覆盖配置文件
CI 中常用组合(以 GitHub Actions 为例):
clang-tidy -p build/ $(find src/ -name '*.cpp') --export-fixes=clang-tidy-fixes.yaml 2>&1 | grep -E "(warning|error):" # 后续可用 clang-apply-replacements 工具批量应用 fixes
容易被忽略的一点:Clang-Tidy 对模板深度 > 10 的代码(如嵌套 std::tuple)可能超时或崩溃,默认限制是 256 —— 如果遇到 fatal error: too many errors emitted, stopping now,需加 -ferror-limit=0 并检查是否真有大量模板实例化问题。











