Clang-Tidy 的介绍及使用(强大的静态代码分析工具)

Clang-Tidy 是一个基于 Clang 的 C++ 静态代码分析工具,旨在帮助开发者发现和修复代码中的潜在问题。它不仅能够检查代码风格、潜在的错误,还能提供自动修复建议,从而提高代码质量和可维护性。本文将介绍 Clang-Tidy 的基本概念、安装方法以及如何使用它来改进你的 C++ 代码。

基本概念

Clang-Tidy 是基于 LLVM 项目的一部分,它利用 Clang 的前端来解析和分析 C++ 代码。Clang-Tidy 提供了丰富的检查器(checks),可以检测多种问题,包括但不限于:

  • 代码风格问题
  • 潜在的编程错误
  • 性能问题
  • 现代 C++ 特性使用建议

安装 Clang-Tidy

Clang-Tidy 通常与 Clang 编译器一起发布。你可以通过以下几种方式安装 Clang-Tidy:

通过包管理器安装

Ubuntu/Debian
sudo apt-get install clang-tidy
macOS
brew install llvm

通过源码编译安装

如果你需要最新的功能和修复,可以通过源码编译安装 Clang-Tidy:

  1. 克隆 LLVM 仓库:

    git clone https://github.com/llvm/llvm-project.git
    
  2. 创建构建目录并进行配置:

    mkdir llvm-project/build
    cd llvm-project/build
    cmake -G "Unix Makefiles" ../llvm
    
  3. 编译并安装:

    make clang-tidy
    sudo make install
    
windows

在windows下这个clang-tidy.exe一般随工具链发布,不用单独安装。可以直接搜索到这个clang-tidy.exe可执行程序。

使用 Clang-Tidy

基本用法

Clang-Tidy 的基本用法非常简单,只需在命令行中指定要检查的文件即可:

clang-tidy your_file.cpp

配置文件

Clang-Tidy 支持通过配置文件来定制检查规则。你可以在项目根目录下创建一个 .clang-tidy 文件,并在其中指定要启用或禁用的检查器。例如:

Checks: '-*,modernize-*,cppcoreguidelines-*,clang-analyzer-*'

自动修复

Clang-Tidy 不仅可以检测问题,还可以提供自动修复建议。使用 -fix 选项可以自动应用修复:

clang-tidy -fix your_file.cpp

集成到构建系统

为了更方便地使用 Clang-Tidy,你可以将其集成到你的构建系统中。以下是一些常见的构建系统的集成方法:

CMake

在 CMake 项目中,你可以使用 add_custom_command 和 add_custom_target 来集成 Clang-Tidy:

find_program(CLANG_TIDY_EXE NAMES clang-tidy)

if(CLANG_TIDY_EXE)
  set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_EXE})
endif()
Makefile

在 Makefile 中,你可以添加一个目标来运行 Clang-Tidy:

CLANG_TIDY = clang-tidy

tidy:
    $(CLANG_TIDY) your_file.cpp --

示例

假设你有一个简单的 C++ 文件 example.cpp

#include <iostream>

int main() {
    int a = 10;
    int b = 0;
    int result = a / b; // 除零错误
    std::cout << "Result: " << result << std::endl;
    return 0;
}

运行 Clang-Tidy 进行检查:

clang-tidy example.cpp

Clang-Tidy 会报告除零错误,并建议修复:

example.cpp:6:16: warning: division by zero is undefined [clang-diagnostic-division-by-zero]
    int result = a / b; // 除零错误
               ^

Cmake中手动使用步骤

1.生成编译数据库:

确保你已经创建了编译数据库。可以使用 CMake 或手动创建 compile_commands.json 文件。

compile_commands.json 文件示例如下:

  [
     {
       "directory": "D:/test",
       "command": "cl.exe /c /nologo /O2 /W3 /std:c++17  test.cpp",
       "file": "D:/test/test.cpp"
     }
   ]
   

 可用CMake 命令自动生成:

 mkdir build
 cd build
 cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
   

2.配置 .clang-tidy 文件

创建一个 .clang-tidy 文件,启用相应的检查规则: 

Checks: 'cppcoreguidelines-*,
performance-*,
modernize-*,
google-*,
misc-*
cert-*,
readability-*,
clang-analyzer-*,
-performance-unnecessary-value-param,
-modernize-use-trailing-return-type,
-google-runtime-references,
-misc-non-private-member-variables-in-classes,
-readability-braces-around-statements,
-google-readability-braces-around-statements,
-cppcoreguidelines-avoid-magic-numbers,
-readability-magic-numbers,
-readability-magic-numbers,
-cppcoreguidelines-pro-type-vararg,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-avoid-c-arrays,
-modernize-avoid-c-arrays,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-readability-named-parameter,
-cert-env33-c
'

3.运行 Clang-Tidy:

使用编译数据库运行 Clang-Tidy。  

clang-tidy -p=D:/test/build test.cpp

经过以上三步,即完成了对一个文件的手动使用完整过程。 

详细介绍

clang-tidy有自己的检查,并且可以运行Clang静态分析器检查。每个检查都有一个名称,可以使用-checks=选项来选择要运行的检查,该选项指定了一个逗号分隔的列表,包括正向和负向(以-为前缀)的全局匹配模式。正向全局匹配模式添加检查的子集,负向全局匹配模式则从中移除。例如:

$ clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus*

将会禁用所有默认检查(-*),并启用所有clang-analyzer-检查,除了clang-analyzer-cplusplus

-list-checks选项列出所有已启用的检查。如果未使用-checks=,它会显示默认启用的检查。使用-checks=*可以查看所有可用的检查,或者与任何其他-checks=的值一起使用,以查看该值启用了哪些检查。

目前有以下几组检查:

名称前缀描述
abseil-与Abseil库相关的检查。
altera-与FPGA的OpenCL编程相关的检查。
android-与Android相关的检查。
boost-与Boost库相关的检查。
bugprone-针对易出错代码结构的检查。
cert-与CERT安全编码指南相关的检查。
clang-analyzer-Clang静态分析器检查。
concurrency-与并发编程相关的检查(包括线程、纤维、协程等)。
cppcoreguidelines-与C++核心指南相关的检查。
darwin-与Darwin编码约定相关的检查。
fuchsia-与Fuchsia编码约定相关的检查。
google-与Google编码约定相关的检查。
hicpp-与高完整性C++编码标准相关的检查。
linuxkernel-与Linux内核编码约定相关的检查。
llvm-与LLVM编码约定相关的检查。
llvmlibc-与LLVM-libc编码标准相关的检查。
misc-我们没有更好分类的检查。
modernize-提倡使用现代(目前“现代”意味着“C++11”)语言结构的检查。
mpi-与MPI(消息传递接口)相关的检查。
objc-与Objective-C编码约定相关的检查。
openmp-与OpenMP API相关的检查。
performance-针对性能相关问题的检查。
portability-针对与任何特定编码风格无关的可移植性相关问题的检查。
readability-针对与任何特定编码风格无关的可读性相关问题的检查。
zircon-与Zircon内核编码约定相关的检查。

Clang诊断与检查诊断类似。Clang诊断由clang-tidy显示,并且可以使用-checks=选项进行过滤。然而,-checks=选项不影响编译参数,因此它不能打开构建配置中尚未打开的Clang警告。-warnings-as-errors=选项将任何在-checks=标志下发出的警告升级为错误(但它本身不启用任何检查)。

Clang诊断的检查名称以clang-diagnostic-开头。具有相应警告选项的诊断,被命名为clang-diagnostic-<警告选项>,例如,由-Wliteral-conversion控制的Clang警告将以检查名称clang-diagnostic-literal-conversion报告。

-fix标志指示clang-tidy在相应检查支持的情况下修复发现的错误。

所有命令行选项的概览:

$ clang-tidy --help

通用选项:

--help | 显示可用选项(--help-hidden显示更多)

--help-list | 显示可用选项列表(--help-list-hidden显示更多)

--version | 显示程序的版本

clang-tidy选项:

--checks=<string> | 逗号分隔的全局匹配列表,可选的'-'前缀。全局匹配按在列表中出现的顺序处理。没有'-'前缀的全局匹配将匹配名称的检查添加到集合中,带有'-'前缀的全局匹配从启用的检查集合中移除检查。此选项的值将追加到.clang-tidy文件中的'Checks'选项的值,如果有的话。

--config=<string> | 指定YAML/JSON格式的配置: --config="{Checks: '*', CheckOptions: {x: y}}" 当值为空时,clang-tidy将尝试为其父目录中的每个源文件找到一个名为.clang-tidy的文件。

--config-file=<string> | 指定.clang-tidy或自定义配置文件的路径: 例如 --config-file=/some/path/myTidyConfigFile 此选项在内部的工作方式与读取指定配置文件后的--config选项完全相同。使用--config-file或--config,不要同时使用两者。

--dump-config | 将配置以YAML格式转储到stdout。此选项可以与文件名一起使用(如果文件在配置了编译数据库的项目外部,则使用'--')。 用于此文件的配置将被打印出来。 与-checks=*一起使用,以包括所有检查的配置。

--enable-check-profile | 启用每个检查的时间配置文件,并在stderr上打印报告。

--enable-module-headers-parsing | 为C++20及以上版本启用预处理器级别的模块头解析,使特定检查能够检测模块内的宏定义。此功能可能会导致性能和解析问题,因此被认为是实验性的。

--exclude-header-filter=<string> | 正则表达式,匹配要排除诊断的头文件名称。每个翻译单元的主文件的诊断总是显示的。 必须与--header-filter一起使用。 可以与--line-filter一起使用。 此选项覆盖.clang-tidy文件中的'ExcludeHeaderFilterRegex'选项,如果有的话。

--explain-config | 对于每个启用的检查解释它在哪里启用,即在clang-tidy二进制文件、命令行或特定配置文件中。

--export-fixes=<filename> | YAML文件,用于存储建议的修复。可以使用clang-apply-replacements将存储的修复应用到输入源代码中。

--extra-arg=<string> | 附加参数,添加到编译器命令行 --extra-arg-before=<string> | 附加参数,预置于编译器命令行 --fix | 应用建议的修复。如果没有-fix-errors,如果发现任何编译错误,clang-tidy将退出。

--fix-errors | 即使发现编译错误,也应用建议的修复。如果编译错误有附加的修复,clang-tidy也将应用它们。

--fix-notes | 如果警告没有修复,但可以通过关联的诊断说明找到一个单一的修复,应用该修复。 指定此标志将隐式启用'--fix'标志。

--format-style=<string> | 应用修复周围代码的样式:

  • 'none'(默认)关闭格式化
  • 'file'(字面意思是'file',不是占位符) 使用最接近父目录中的.clang-format文件
  • '{ <json> }' 内联指定选项,例如-format-style='{BasedOnStyle: llvm, IndentWidth: 8}'

总结

Clang-Tidy 是一个强大的 C++ 静态代码分析工具,能够帮助开发者发现和修复代码中的潜在问题。通过配置文件和自动修复功能,你可以更高效地改进代码质量。将其集成到你的构建系统中,可以进一步提高开发效率和代码可靠性。希望本文能帮助你更好地理解和使用 Clang-Tidy,提升你的 C++ 编程技能。

Clang-Tidy — Extra Clang Tools 20.0.0git documentation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特立独行的猫a

您的鼓励是我的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值