Clang-Tidy

← 返回目录 > ← 返回总览

相关工具推荐

工具 说明
ClangFormat C/C++/Java/ObjC 代码格式化工具,与 Clang-Tidy 互补
Cppcheck C/C++ 静态分析工具,独立于编译器的轻量级检查
CodeQL GitHub 官方代码分析引擎,支持 C/C++ 安全分析
Pre-commit 多语言 Git 钩子管理框架,Clang-Tidy 的主流集成方式之一

1. 简介

Clang-Tidy 是基于 Clang 编译器的 C/C++ 静态分析与代码检查工具,属于 LLVM/Clang 工具链的一部分(代码位于 llvm-project 仓库的 clang-tools-extra 目录)。它提供了一个可扩展的框架,用于诊断和修复典型的编程错误,包括代码风格违规、接口误用以及可通过静态分析推断出的 Bug。

  • 主要检查语言:C、C++
  • 主要检查能力:检测 C/C++ 代码中的 Bug、性能问题、代码异味、安全漏洞;涵盖质量类检查(bugprone、cert)、风格类检查(readability、google、llvm)、性能检查(performance)、现代化迁移(modernize)、安全检查(cert、concurrency)
  • 核心检查原理:基于 Clang AST 深度分析,模块化检查器架构
  • 检查规则/选项:数百个 check(随 LLVM 版本动态变化,按 abseil、bugprone、modernize、performance、readability 等 20+ 模块分组),全量 check 列表
  • GitHub 仓库https://github.com/llvm/llvm-project(LLVM 子项目,38,776 stars,LLVM 主仓库,Clang-Tidy 无独立仓库)
  • 开源协议:Apache-2.0 with LLVM Exceptions
  • 最新稳定版本:随 LLVM 22.1.0 发布(2026-02-24,无独立版本号)
  • 运行环境要求:需 LLVM/Clang 工具链;随 LLVM 版本发布
  • 误报率:中

2. 官方文档

资源 链接
Clang-Tidy 使用指南 https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html
所有检查规则列表 https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/checks/list.html
告警抑制文档(NOLINT 等) https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html#suppressing-undesired-diagnostics
IDE/编辑器集成指南 https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/Integrations.html
外部 Clang-Tidy 示例 https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/ExternalClangTidyExamples.html
贡献指南(编写自定义检查) https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/Contributing.html
LLVM Releases 下载页 https://releases.llvm.org/
GitHub 仓库 https://github.com/llvm/llvm-project

3. 社区优秀实践

3.1 LLVM

LLVM 项目自身就是 Clang-Tidy 的开发项目,自然也是其最重要的实践者。LLVM 在项目根目录维护了 .clang-tidy 配置文件,启用 llvm-*misc-*readability-identifier-naming 等检查组,并通过 CMAKE_CXX_CLANG_TIDY 集成到构建流程中。LLVM 还提供了 run-clang-tidy.pyclang-tidy-diff.py 等官方辅助脚本。

3.2 Chromium

Chromium 是全球最大的 C++ 开源项目之一,在项目根目录维护了 .clang-tidy 配置文件,将 Clang-Tidy 深度集成到代码审查流程中。Chromium 通过 PRESUBMIT.py 脚本在代码提交前自动运行 Clang-Tidy 检查,确保代码质量。

3.3 WebKit

WebKit 是另一个大型 C++ 开源项目,在项目中使用了 Clang-Tidy 进行代码质量检查。WebKit 项目维护了自己的 .clang-tidy 配置,针对浏览器引擎的特殊需求定制了检查规则。


4. 工具配置说明

4.1 配置文件说明

Clang-Tidy 使用 YAML 格式的 .clang-tidy 配置文件。

配置文件 用途 使用场景
.clang-tidy 项目级检查规则配置 放置在项目根目录,Clang-Tidy 从源文件最近的父目录中查找

文件查找与继承机制

  • 从源文件所在目录向上逐级查找 .clang-tidy 文件
  • 支持子目录覆盖父目录配置(通过 InheritParentConfig: true
  • 命令行 -config 参数可内联指定配置

4.2 .clang-tidy 配置详解

配置项说明

配置项 类型 说明
Checks string 启用/禁用的检查规则(逗号分隔的通配符列表,- 前缀表示禁用)
WarningsAsErrors string 将指定警告升级为错误的规则列表
HeaderFilterRegex string 头文件过滤正则(控制哪些头文件中的诊断会被显示)
ExcludeHeaderFilterRegex string 排除头文件过滤正则
FormatStyle string 代码修复时的格式化风格(filellvmgoogle 等)
InheritParentConfig bool 是否继承父目录的配置文件
HeaderFileExtensions string[] 头文件扩展名列表
ImplementationFileExtensions string[] 实现文件扩展名列表
SystemHeaders bool 是否显示系统头文件中的诊断
UseColor bool 是否使用颜色输出
ExtraArgs string[] 额外的编译参数(追加在命令行末尾)
ExtraArgsBefore string[] 额外的编译参数(追加在命令行开头)
RemovedArgs string[] 需要移除的编译参数
CheckOptions list 检查特定选项(键值对列表,每项含 keyvalue
User string 运行 clang-tidy 的用户名(用于 TODO 注释等)

最小配置示例

---
Checks: "bugprone-*,modernize-*"
HeaderFilterRegex: ".*"
FormatStyle: file

推荐配置示例(适合大多数 C++ 项目):

---
# .clang-tidy
# 通用 C++ 项目推荐配置
# 策略:先禁用所有默认检查,再按需启用推荐规则组

Checks: >
  -*,
  bugprone-*,
  -bugprone-easily-swappable-parameters,
  -bugprone-narrowing-conversions,
  -bugprone-assignment-in-if-condition,
  modernize-*,
  -modernize-use-trailing-return-type,
  -modernize-avoid-c-arrays,
  performance-*,
  readability-*,
  -readability-magic-numbers,
  -readability-function-cognitive-complexity,
  -readability-identifier-length,
  cppcoreguidelines-*,
  -cppcoreguidelines-avoid-magic-numbers,
  -cppcoreguidelines-pro-bounds-pointer-arithmetic,
  -cppcoreguidelines-pro-type-reinterpret-cast,
  -cppcoreguidelines-avoid-c-arrays,
  cert-*,
  -cert-err58-cpp,
  concurrency-*

HeaderFilterRegex: ".*"
FormatStyle: file
WarningsAsErrors: ""
CheckOptions:
  # modernize-use-nullptr: 指定需要替换的 NULL 宏
  - key: modernize-use-nullptr.NullMacros
    value: "NULL"
  # modernize-use-override: 是否忽略类中无虚函数的记录
  - key: modernize-use-override.IgnoreDestructors
    value: true
  # readability-identifier-naming: 命名规范
  - key: readability-identifier-naming.ClassCase
    value: "CamelCase"
  - key: readability-identifier-naming.StructCase
    value: "CamelCase"
  - key: readability-identifier-naming.FunctionCase
    value: "camelBack"
  - key: readability-identifier-naming.VariableCase
    value: "camelBack"
  - key: readability-identifier-naming.PrivateMemberSuffix
    value: "_"
  - key: readability-identifier-naming.ParameterCase
    value: "camelBack"
  - key: readability-identifier-naming.ConstexprVariableCase
    value: "UPPER_CASE"
  - key: readability-identifier-naming.GlobalConstantCase
    value: "UPPER_CASE"
  - key: readability-identifier-naming.EnumConstantCase
    value: "UPPER_CASE"
  - key: readability-identifier-naming.NamespaceCase
    value: "lower_case"
  # performance-*: 性能相关选项
  - key: performance-unnecessary-value-param.AllowedTypes
    value: ""

4.3 规则说明

bugprone-*(Bug 倾向检查)

检测容易出错的代码构造,是发现实际 Bug 最有效的规则组。

规则 说明 建议启用
bugprone-argument-comment 检测参数注释与实际参数不匹配
bugprone-assert-side-effect 检测 assert 中的副作用
bugprone-bool-pointer-implicit-conversion 检测 bool 指针的隐式转换
bugprone-copy-constructor-init 检测拷贝构造函数中的初始化问题
bugprone-dangling-handle 检测悬空句柄
bugprone-easily-swappable-parameters 检测容易混淆的参数顺序 视情况
bugprone-exception-escape 检测不应抛出异常的函数中存在异常
bugprone-inc-dec-in-conditions 检测条件中的自增/自减操作
bugprone-inaccurate-erase 检测不正确的 erase 用法
bugprone-incorrect-roundings 检测不正确的四舍五入
bugprone-integer-division 检测整数除法截断
bugprone-macro-parentheses 检测宏定义缺少括号
bugprone-macro-repeated-side-effects 检测宏中的重复副作用
bugprone-misplaced-operator-in-strlen-in-alloc 检测 strlen/malloc 中的运算符错误
bugprone-move-forwarding-reference 检测转发引用的错误移动
bugprone-narrowing-conversions 检测窄化转换 视情况
bugprone-parent-virtual-call 检测构造/析构中的虚函数调用
bugprone-redundant-branch-condition 检测冗余的分支条件
bugprone-redundant-string-cstr 检测多余的 string.c_str()
bugprone-signal-handler 检测信号处理函数中的不安全操作
bugprone-sizeof-container 检测对容器使用 sizeof
bugprone-string-constructor 检测低效的字符串构造
bugprone-suspicious-include 检测可疑的 #include
bugprone-suspicious-memset 检测可疑的 memset 用法
bugprone-suspicious-missing-comma 检测缺少逗号导致的错误
bugprone-suspicious-semicolon 检测可疑的分号
bugprone-suspicious-string-compare 检测可疑的字符串比较
bugprone-swapped-arguments 检测参数顺序颠倒
bugprone-throw-keyword-missing 检测缺少 throw 关键字
bugprone-unchecked-optional-access 检测未检查的 optional 访问
bugprone-unique-ptr-array-mismatch 检测 unique_ptr 数组不匹配
bugprone-unused-return-value 检测未使用的返回值
bugprone-use-after-move 检测移动后的使用

modernize-*(现代化检查)

倡导使用现代 C++(C++11 及以上)语言特性,帮助代码迁移到现代 C++ 标准。

规则 说明 建议启用
modernize-use-auto 使用 auto 替代冗长的类型声明
modernize-use-nullptr 使用 nullptr 替代 NULL/0
modernize-use-override 使用 override 关键字
modernize-use-using 使用 using 替代 typedef
modernize-use-enum-class 使用 enum class
modernize-use-noexcept 使用 noexcept
modernize-use-default-member-init 使用默认成员初始化器
modernize-use-emplace 使用 emplace 替代 push_back + 构造
modernize-use-equals-default 使用 = default
modernize-use-equals-delete 使用 = delete
modernize-use-nodiscard 添加 [[nodiscard]] 属性
modernize-use-trailing-return-type 使用尾置返回类型 视情况
modernize-loop-convert 将 for 循环转换为 range-for
modernize-make-shared 使用 std::make_shared
modernize-make-unique 使用 std::make_unique
modernize-redundant-void-arg 移除冗余的 void 参数
modernize-shrink-to-fit 使用 shrink_to_fit
modernize-replace-auto-ptr 替换 auto_ptr
modernize-deprecated-headers 使用 C++ 头文件替代 C 头文件
modernize-avoid-c-arrays 避免使用 C 风格数组 视情况
modernize-avoid-bind 使用 lambda 替代 std::bind
modernize-pass-by-value 对仅移动参数使用按值传递 视情况

performance-*(性能检查)

检测与性能相关的问题。

规则 说明 建议启用
performance-unnecessary-value-param 检测不必要的值传递参数
performance-unnecessary-copy-initialization 检测不必要的拷贝初始化
performance-for-range-copy 检测 range-for 中不必要的拷贝
performance-inefficient-string-concatenation 检测低效的字符串拼接
performance-inefficient-vector-operation 检测低效的 vector 操作
performance-faster-string-find 使用更快的字符串查找方法
performance-no-int-to-ptr 检测整数到指针的转换
performance-type-promotion-in-math-fn 检测数学函数中的类型提升
performance-move-const-arg 检测对 const 值的移动
performance-noexcept-swap swap 函数应标记 noexcept
performance-implicit-conversion-in-loop 检测循环中的隐式转换

readability-*(可读性检查)

提升代码可读性,不关联特定代码风格。

规则 说明 建议启用
readability-identifier-naming 统一命名规范
readability-braces-around-statements 控制语句使用大括号
readability-const-return-type 移除返回类型中的 const
readability-container-size-empty 使用 empty() 替代 size() == 0
readability-else-after-return 移除 return 后的 else
readability-redundant-control-flow 移除冗余的控制流
readability-redundant-string-cstr 移除多余的 c_str()
readability-redundant-preprocessor 检测冗余的预处理器指令
readability-simplify-boolean-expr 简化布尔表达式
readability-simplify-subscript-expr 简化下标表达式
readability-static-accessed-through-instance 通过实例访问静态成员
readability-string-compare 简化字符串比较
readability-uniqueptr-delete-release 用 reset() 替代 delete + release
readability-implicit-bool-conversion 检测隐式布尔转换
readability-function-cognitive-complexity 函数认知复杂度 视情况
readability-function-size 函数长度限制 视情况
readability-magic-numbers 魔法数字检测 视情况
readability-identifier-length 标识符长度 视情况
readability-duplicate-include 检测重复的 #include
readability-misleading-indentation 检测误导性缩进
readability-redundant-declaration 检测冗余声明
readability-inconsistent-declaration-parameter-name 参数名不一致

cppcoreguidelines-*(C++ Core Guidelines 检查)

基于 C++ Core Guidelines 的检查规则。

规则 说明 建议启用
cppcoreguidelines-avoid-goto 避免 goto
cppcoreguidelines-prefer-member-initializer 使用成员初始化器
cppcoreguidelines-pro-type-static-cast-downcast 使用 static_cast 替代向下转换
cppcoreguidelines-pro-type-reinterpret-cast 警告 reinterpret_cast 使用 视情况
cppcoreguidelines-pro-type-const-cast 警告 const_cast 使用 视情况
cppcoreguidelines-pro-type-cstyle-cast 避免 C 风格转换
cppcoreguidelines-pro-bounds-pointer-arithmetic 避免指针算术 视情况
cppcoreguidelines-pro-bounds-constant-array-index 避免非常量数组索引
cppcoreguidelines-slicing 检测对象切片
cppcoreguidelines-owning-memory 检测资源所有权问题
cppcoreguidelines-special-member-functions 检测特殊成员函数的一致性
cppcoreguidelines-init-variables 变量应被初始化
cppcoreguidelines-rvalue-reference-param-not-moved 右值引用参数未被移动

cert-*(CERT 安全编码检查)

基于 CERT Secure Coding Standards 的安全检查。

规则 说明 建议启用
cert-dcl50-cpp 禁止动态异常规范
cert-dcl58-cpp 禁止在未导出的命名空间中定义
cert-err33-c 检测未处理的返回值
cert-err52-cpp 检测多次移动
cert-err60-cpp 检测解引用已移动的对象
cert-flp30-c 检测循环中的浮点比较
cert-msc50-cpp 检测不安全的随机数生成
cert-msc51-cpp 检测不准确的随机数
cert-oop57-cpp 检测在构造/析构中的虚调用
cert-oop58-cpp 检测拷贝构造函数中修改参数

concurrency-*(并发检查)

检测与并发编程相关的问题。

规则 说明 建议启用
concurrency-mt-unsafe 检测非线程安全的函数调用
concurrency-thread-canceltype-asynchronous 检测异步取消类型

4.4 渐进式引入策略

对于已有的大型项目,建议采用渐进式引入策略:

  1. 第一阶段:仅启用 bugprone-*modernize-use-automodernize-use-nullptrmodernize-use-override 等高频低风险检查
  2. 第二阶段:逐步启用 performance-*readability-* 中的核心规则
  3. 第三阶段:启用 cppcoreguidelines-*cert-* 安全相关规则
  4. 第四阶段:启用 clang-analyzer-* 深度静态分析(注意性能开销)
---
# .clang-tidy - 第一阶段(入门)
Checks: >
  -*,
  bugprone-*,
  -bugprone-easily-swappable-parameters,
  modernize-use-auto,
  modernize-use-nullptr,
  modernize-use-override,
  modernize-use-using,
  modernize-use-enum-class,
  modernize-loop-convert,
  modernize-make-shared,
  modernize-make-unique,
  modernize-redundant-void-arg,
  modernize-deprecated-headers,
  modernize-replace-auto-ptr,
  readability-braces-around-statements,
  readability-else-after-return,
  readability-container-size-empty,
  readability-redundant-string-cstr,
  readability-simplify-boolean-expr,
  performance-for-range-copy,
  performance-move-const-arg,
  performance-noexcept-swap

HeaderFilterRegex: ".*"
FormatStyle: file
WarningsAsErrors: ""

5. 主流集成方式

5.1 CMake 集成(生态主流)

CMake 是 C/C++ 项目的主流构建工具,也是 Clang-Tidy 最常见的集成方式。Clang-Tidy 依赖 compile_commands.json 编译数据库来获取编译参数。

方式一:通过 CMAKE_CXX_CLANG_TIDY 变量

CMakeLists.txt 中设置,使 Clang-Tidy 在每次编译时自动运行:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(MyProject LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 导出编译命令数据库(Clang-Tidy 依赖此文件)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# 查找 clang-tidy 并设置
find_program(CLANG_TIDY_COMMAND NAMES "clang-tidy" "clang-tidy-18" "clang-tidy-17")
if(CLANG_TIDY_COMMAND)
    set(CMAKE_CXX_CLANG_TIDY
        ${CLANG_TIDY_COMMAND}
        --config-file=${CMAKE_SOURCE_DIR}/.clang-tidy
    )
    message(STATUS "Clang-Tidy enabled: ${CLANG_TIDY_COMMAND}")
endif()

方式二:通过自定义 target

# CMakeLists.txt - 定义独立的 tidy target
find_program(CLANG_TIDY_EXE NAMES "clang-tidy")
if(CLANG_TIDY_EXE)
    add_custom_target(
        clang-tidy
        COMMAND ${CLANG_TIDY_EXE} -p ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        COMMENT "Running Clang-Tidy..."
        VERBATIM
    )
endif()

生成编译数据库:

cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

5.2 pre-commit 集成

使用 pocc/pre-commit-hooks 仓库提供的预置 hook,可在 Git 提交前自动运行 Clang-Tidy 检查暂存文件。

依赖说明:此 hook 依赖本地安装的 clang-tidy(需在 PATH 中可用),以及项目的 compile_commands.json 编译数据库。hook 使用 language: python,但实际调用的是系统中的 clang-tidy 二进制。

# .pre-commit-config.yaml
fail_fast: false
repos:
  - repo: https://github.com/pocc/pre-commit-hooks
    rev: v1.3.5
    hooks:
      - id: clang-tidy
        args: [-p, build]
        # 可选:锁定 clang-tidy 版本,确保团队一致
        # args: [--version=18.1.0, -p, build]

安装 pre-commit hooks:

pip install pre-commit
pre-commit install

限制变更文件:pre-commit 框架默认仅将暂存区中的变更文件传给 hook,因此无需额外配置即可实现文件级增量检查。

5.3 IDE 集成

VS Code

通过 clangd 扩展实现 Clang-Tidy 集成(官方推荐方式):

// .vscode/settings.json
{
  "clangd.arguments": [
    "--clang-tidy",
    "--background-index",
    "--header-insertion=iwyu",
    "--completion-style=detailed",
    "-j=12"
  ],
  "clangd.fallbackFlags": ["-std=c++17"]
}

也可使用独立的 Clang-Tidy 扩展(notskm.clang-tidy)。

CLion

CLion 内置 Clang-Tidy 支持,默认启用:

  1. 进入 Settings | Editor | Inspections | C/C++ | Static Analysis Tools | Clang-Tidy
  2. 配置启用的检查规则列表
  3. 支持从编辑器中快速禁用/抑制特定检查
  4. 支持通过状态栏小部件管理 .clang-tidy 配置文件

参考文档:https://www.jetbrains.com/help/clion/clang-tidy-checks-support.html

Vim/Neovim

方式一:通过 clangd(推荐)

使用 coc-clangd 或 Neovim 内置 LSP 配置:

-- Neovim init.lua
vim.lsp.config.clangd = {
    cmd = {
        "clangd",
        "--clang-tidy",
        "--background-index",
        "--header-insertion=iwyu",
    },
}

方式二:通过 ALE

" .vimrc
let g:ale_linters = {
    \ 'cpp': ['clangtidy'],
    \ 'c': ['clangtidy'],
    \}
let g:ale_cpp_clangtidy_options = '-p build'

5.4 命令行使用方式

# 基本检查(使用编译数据库)
clang-tidy -p build src/main.cpp

# 基本检查(手动指定编译参数)
clang-tidy src/main.cpp -- -std=c++17 -I./include

# 指定检查规则
clang-tidy -p build src/main.cpp -checks='bugprone-*,modernize-*'

# 自动修复问题
clang-tidy -p build src/main.cpp -fix

# 自动修复(包括编译错误)
clang-tidy -p build src/main.cpp -fix -fix-errors

# 导出修复建议到 YAML 文件
clang-tidy -p build src/main.cpp -export-fixes=fixes.yaml

# 列出所有可用检查
clang-tidy -list-checks -checks='*'

# 列出默认启用的检查
clang-tidy -list-checks

# 验证配置文件是否正确
clang-tidy -p build --verify-config

# 导出当前生效的配置
clang-tidy -p build --dump-config

# 并行检查整个项目(使用 run-clang-tidy.py)
run-clang-tidy.py -p build -j 8

# 指定头文件过滤
clang-tidy -p build src/main.cpp -header-filter='src/.*\.h'

# 排除特定头文件
clang-tidy -p build src/main.cpp -header-filter='src/.*\.h' -exclude-header-filter='third_party/.*'

增量检查 -- Clang-Tidy 提供多种增量检查方式:

使用 clang-tidy-diff.py(官方脚本) -- Clang-Tidy 自带 clang-tidy-diff.py 脚本,可仅对 Git diff 中的变更行进行检查:

# 检查工作目录中的变更(相对于上一个 commit)
git diff -U0 --no-color HEAD | clang-tidy-diff.py -p1

# 检查暂存区的变更
git diff -U0 --no-color --cached | clang-tidy-diff.py -p1

# 检查两个 commit 之间的差异
git diff -U0 --no-color HEAD~2 HEAD | clang-tidy-diff.py -p1

# 指定检查规则并自动修复
git diff -U0 --no-color HEAD | clang-tidy-diff.py -p1 -fix -checks='-*,bugprone-*,modernize-*'

注意clang-tidy-diff.py 仍然会分析整个文件,只是在输出时过滤掉未变更行的诊断。因此它不会提升分析性能,但能让输出更聚焦于变更代码。

参考文档:https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html#running-clang-tidy-on-diff

使用 run-clang-tidy.py 并行检查

# 并行检查整个项目(默认使用所有 CPU 核心)
run-clang-tidy.py -p build -j 8

# 仅检查指定目录
run-clang-tidy.py -p build -j 8 src/

# 检查并自动修复
run-clang-tidy.py -p build -j 8 -fix

参考文档:https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html#running-clang-tidy-in-parallel

基于 Git 的命令行增量方案

# 获取相对于 HEAD 的 C++ 变更文件
git diff --name-only --diff-filter=ACMR HEAD -- '*.cpp' '*.h' '*.cc' '*.cxx' '*.hpp' | \
    xargs -I{} clang-tidy -p build {}

# 获取相对于 main 分支的变更文件
git diff --name-only --diff-filter=ACMR main...HEAD -- '*.cpp' '*.h' | \
    xargs -I{} clang-tidy -p build {}

使用 --line-filter 仅检查特定行范围

# 使用 --line-filter 指定文件和行范围(JSON 格式)
clang-tidy -p build src/main.cpp --line-filter='[{"name":"src/main.cpp","lines":[[10,50],[100,120]]}]'

CI 脚本调用

GitHub Actions

# .github/workflows/clang-tidy.yml
name: Clang-Tidy

on: [push, pull_request]

jobs:
  clang-tidy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Clang-Tidy
        run: sudo apt-get update && sudo apt-get install -y clang-tidy

      - name: Configure CMake
        run: cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

      - name: Run Clang-Tidy
        run: |
          cd build
          run-clang-tidy.py -p . -checks='-*,bugprone-*,modernize-*,readability-*,performance-*' 2>&1 | tee clang-tidy-report.txt
        continue-on-error: true

      - name: Upload Report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: clang-tidy-report
          path: build/clang-tidy-report.txt

GitLab CI

# .gitlab-ci.yml
clang-tidy:
  stage: test
  image: ubuntu:latest
  before_script:
    - apt-get update && apt-get install -y clang-tidy cmake build-essential
    - cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
  script:
    - run-clang-tidy.py -p build -quiet
  artifacts:
    paths:
      - clang-tidy-report.txt
    when: always

增量检查 -- 按 PR 变更文件触发增量扫描:

GitHub Actions(按 PR 变更文件触发)

# .github/workflows/clang-tidy.yml
name: Clang-Tidy (Incremental)

on: [pull_request]

jobs:
  clang-tidy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Clang-Tidy
        run: sudo apt-get update && sudo apt-get install -y clang-tidy

      - name: Configure CMake
        run: cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

      - name: Run Clang-Tidy on changed files
        run: |
          CHANGED_FILES=$(git diff --name-only --diff-filter=ACMR origin/${{ github.base_ref }}...HEAD -- '*.cpp' '*.h' '*.cc' '*.cxx' '*.hpp')
          if [ -n "$CHANGED_FILES" ]; then
            echo "$CHANGED_FILES" | xargs -I{} clang-tidy -p build {}
          else
            echo "No C/C++ files changed."
          fi

6. 告警抑制(屏蔽)方法

Clang-Tidy 提供了多种告警抑制机制,从代码级注释到配置文件级别均可控制。

参考文档:https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html#suppressing-undesired-diagnostics

6.1 通过代码注释屏蔽(NOLINT)

// NOLINT -- 抑制当前行所有警告

int x = 1;  // NOLINT

// NOLINT(check-name) -- 抑制当前行指定检查

int x = 1;  // NOLINT(bugprone-narrowing-conversions)

// NOLINTNEXTLINE -- 抑制下一行的警告

// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
void f(int a, int b, int c);

// NOLINTNEXTLINE(check-name) -- 抑制下一行指定检查

// NOLINTNEXTLINE(google-explicit-constructor, google-runtime-int)
Foo(bool param);

// NOLINTBEGIN ... // NOLINTEND -- 抑制多行警告

// NOLINTBEGIN(google-explicit-constructor)
Foo(short param);
Foo(long param);
Foo(unsigned param);
// NOLINTEND(google-explicit-constructor)

使用通配符批量抑制

// 抑制当前行所有 google 模块的检查
Foo(bool param);  // NOLINT(google*)

// 抑制下一行所有以 -avoid-c-arrays 结尾的检查
// NOLINTNEXTLINE(*-avoid-c-arrays)
int array[10];

附带原因说明(推荐)

// NOLINT: Allow implicit conversion from char, because legacy API requires it
Foo(char param);

语法要求

  • NOLINT/NOLINTNEXTLINE/NOLINTBEGIN/NOLINTEND 与左括号之间不允许有空格,否则会被视为无参数的注释
  • 括号内的检查名列表中,空格会被忽略
  • NOLINTBEGINNOLINTEND 必须成对出现,且参数必须匹配

6.2 通过 .clang-tidy 配置文件屏蔽

在配置文件中使用负通配符排除特定检查,或通过 HeaderFilterRegex 排除特定目录:

# 在 Checks 中使用负通配符排除特定检查
Checks: >
  -*,
  bugprone-*,
  -bugprone-easily-swappable-parameters,
  -bugprone-narrowing-conversions

# 通过 HeaderFilterRegex 排除特定头文件
HeaderFilterRegex: "src/.*"
ExcludeHeaderFilterRegex: "third_party/.*|generated/.*"

参考文档:https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html#configuration-files

6.3 通过命令行参数屏蔽

# 使用 -checks 排除特定检查
clang-tidy -p build src/main.cpp -checks='-*,bugprone-*,-bugprone-easily-swappable-parameters'

# 使用 --header-filter 控制头文件诊断
clang-tidy -p build src/main.cpp --header-filter='src/.*' --exclude-header-filter='third_party/.*'

# 使用 --line-filter 限制检查范围
clang-tidy -p build src/main.cpp --line-filter='[{"name":"src/main.cpp","lines":[[1,50]]}]'

参考文档:https://releases.llvm.org/22.1.0/tools/clang/tools/extra/docs/clang-tidy/index.html#using-clang-tidy

6.4 通过 IDE 屏蔽

在 CLion 中,可以通过右键点击警告选择 Suppress 'check_name' for line,IDE 会自动添加 // NOLINT 注释。也可通过 #pragma clang diagnostic 实现更精细的控制。

参考文档:https://www.jetbrains.com/help/clion/clang-tidy-checks-support.html



← 返回目录 > ← 返回总览