Clang-Tidy


文档摘要

Clang-Tidy是一个用于C和C++代码的linter和静态分析工具。它是Clang和LLVM项目的一部分。这个工具建立在Clang前端之上,这意味着它深入理解你的代码,从而能够捕捉到一系列问题。 以下是关于Clang-Tidy的一些关键要点: 检查:Clang-Tidy包含一系列"检查",用于识别各种问题或提出改进建议。这些检查从性能改进和潜在错误到编码风格和现代C++最佳实践。可能会建议在某些情况下使用emplaceback而不是pushback,或者识别无意中使用整数溢出的区域。 可扩展性:可以向Clang-Tidy添加新的检查,使其成为一个高度可扩展的工具。如果有特定的编码指南或实践想要执行,可以为它编写一个检查。

Clang-Tidy是一个用于C和C++代码的linter和静态分析工具。它是Clang和LLVM项目的一部分。这个工具建立在Clang前端之上,这意味着它深入理解你的代码,从而能够捕捉到一系列问题。

以下是关于Clang-Tidy的一些关键要点:

  • 检查:Clang-Tidy包含一系列"检查",用于识别各种问题或提出改进建议。这些检查从性能改进和潜在错误到编码风格和现代C++最佳实践。可能会建议在某些情况下使用emplace_back而不是push_back,或者识别无意中使用整数溢出的区域。

  • 可扩展性:可以向Clang-Tidy添加新的检查,使其成为一个高度可扩展的工具。如果有特定的编码指南或实践想要执行,可以为它编写一个检查。

  • 集成:Clang-Tidy经常在CI/CD中使用或在开发环境中集成。许多IDE直接支持Clang-Tidy或通过插件支持,因此
    可以在编写代码时实时获得反馈。

  • 自动修复:Clang-Tidy的一个强大功能是它不仅能识别问题,还能自动修复许多问题。这是通过-fix选项实现的。然而,重要的是要审查建议的更改,因为自动修复可能并不总是完美的。

  • 配置:可以使用配置文件或命令行选项配置Clang-Tidy执行哪些检查。这允许团队强制执行特定的编码标准或优先处理某些类型的问题。例如,-checks=’-,modernize-’命令行选项将禁用所有检查,但不禁用modernize集合中的检查。

  • 现代C++最佳实践:Clang-Tidy的一个经常受到赞赏的功能是它强调现代C++习惯用语和最佳实践。它可以指导开发者编写更安全、性能更好、更符合习惯用法的C++代码。

了解了关于Clang-Tidy的基本知识后,让我们看看如何构建它。

使用图1.4中指定的基本构建配置来构建Clang-Tidy,使用以下Ninja命令:

$`ninja clang-tidy
\end{shell}

\begin{center}
图5.1:使用Ninja命令构建Clang-Tidy
\end{center}

使用以下命令将Clang-Tidy二进制文件安装到指定的安装文件夹:

\begin{shell}`$ ninja install-clang-tidy

图5.2:使用Ninja命令安装Clang-Tidy

使用图1.4中的构建配置,命令会将Clang-Tidy二进制文件安装到<…>/llvm-project/install/bin文件夹。<…>/llvm-project指的是克隆LLVM代码库的路径(见图1.1)。

重要提示
如果使用了一个带有动态库(BUILD_SHARED_LIBS标志设置为ON)的构建配置,如图1.12所示,可能需要使用ninja
install命令来安装和构建所有工件。

Clang-Tidy是Clang-Tools-Extra的一部分,其测试是clang-tools
CMake目标的一部分。因此,可以使用以下命令运行测试:

$`ninja check-clang-tools
\end{shell}

\begin{center}
图5.3:使用Ninja命令运行Clang-Tidy测试
\end{center}

该命令将运行LIT测试(见第4.5.2节,LLVM测试框架)的所有Clang-Tidy检查,还将运行Clang-Tidy核心系统的单元测试。也可以单独运行特定的LIT测试,如果想运行modernize-loop-convert检查的LIT测试,可以使用以下命令:

\begin{shell}$ cd \<...\>/llvm-project $build/bin/llvm-lit -v
clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
\end{shell}

\begin{center}
图5.4:测试modernize-loop-convert Clang-Tidy检查
\end{center}

该命令将产生以下输出:

\begin{shell}
-- Testing: 1 tests, 1 workers --
PASS: Clang Tools :: clang-tidy/checkers/modernize/loop-convert-basic.cpp
(1 of 1)

Testing Time: 1.38s
Passed: 1
\end{shell}

\begin{center}
图5.5:cppcoreguidelines-owning-memory Clang-Tidy检查的LIT测试输出
\end{center}

构建和测试Clang-Tidy之后,现在是时候在某些代码示例上运行了。

\mySubsubsection{5.2.2.}{Clang-Tidy的用法}

为了测试Clang-Tidy,使用以下测试程序:

\begin{cpp}
#include
#include

int main() {
std::vector numbers = {1, 2, 3, 4, 5};
for (std::vector::iterator it = numbers.begin(); it != numbers.end();
++it) {
std::cout << *it << std::endl;
}
return 0;
}
\end{cpp}

\begin{center}
图5.6:Clang-Tidy测试程序:loop-convert.cpp
\end{center}

该程序以旧式的C++代码风格编写,即在C++11之前。Clang-Tidy有一系列检查鼓励采用现代C++代码风格和使用最新C++标准中可用的新的C++习语。这些检查可以按以下方式在程序上运行:

\begin{shell}
1`$ <...>/llvm-project/install/bin/clang-tidy  2
-checks=’-*,modernize-*’  3 loop-convert.cpp  4 – -std=c++17

图5.7:在loop-convert.cpp上运行Clang-Tidy modernize检查

图5.7中最重要的部分如下:

  • 第1行:指定了Clang-Tidy二进制文件的路径。

  • 第2行:使用’-*’选项移除了所有检查。然后,使用’–checks’参数的’-*,modernize’值来启用所有以’modernize’前缀开头的检查。

  • 第3行:指定要测试的代码路径。

  • 第4行:向编译器传递参数,特别是指定希望编译器使用C++17作为C++标准。

程序的输出将是:

图5.8:在loop-convert.cpp上运行Clang-Tidy的输出

检测到了几个问题,Clang-Tidy建议了一些修复方案。不幸的是,其中一些相互冲突,特别是modernize-loop-convert和modernize-use-auto,不能同时应用。另一方面,可以单独运行modernize-loop-convert检查,避免冲突,并应用该检查提出的修复方案:

图5.9:在loop-convert.cpp上运行modernize-loop-convert检查

第2行与图5.7中的第2行不同,并添加了另一行(第3行)。后者指示Clang-Tidy应用检查提出的修复方案。修复后的代码可以在原始文件中找到:

#include <iostream> #include <vector>

int main() std::vector<int> numbers = 1, 2, 3, 4, 5; for (int & number
: numbers) std::cout << number << std::endl; return 0;

图5.10:Clang-Tidy修复后的测试程序:loop-convert.cpp

与图5.6中的原始代码相比,第6行和第7行已发生变化。这使得Clang-Tidy成为一个强大的工具,不仅可以检测问题,还可以修复它们。

Clang-Tidy有多种检查,分为不同的类别。以下是主要类别的一些简短列表,每个类别都包含一个示例检查和简要描述:

  1. boost-*:

    • boost-use-to-string: 建议将 boost::lexical_cast<std::string>
      替换为 boost::to_string
  2. bugprone-*:

    • bugprone-integer-division:
      当整数除法在浮点数上下文中,可能导致精度意外丢失时发出警告
  3. cert-* (与CERT C++安全编码标准相关的检查):

    • cert-dcl03-c: 确保宏不用于不安全的上下文
  4. cppcoreguidelines-* (来自C++核心指南的检查):

    • cppcoreguidelines-slicing:
      警告切片(对象切片,其中派生对象被赋值给基对象,切掉派生部分)
  5. google-* (Google的编码规范):

    • google-build-using-namespace: 标记 using-directives
  6. llvm-* (LLVM编码规范):

    • llvm-namespace-comment: 确保命名空间有结束注释
  7. misc-* (杂项检查):

    • misc-unused-parameters: 标记未使用的参数
  8. modernize-* (C++现代化检查):

    • modernize-use-auto: 建议在适当的情况下使用auto进行变量声明
  9. performance-*:

    • performance-faster-string-find: 建议使用更快的字符串搜索替代方案
  10. readability-*:

    • readability-identifier-naming: 确保标识符命名一致

这只是可用检查的一个子集的表示。每个类别都包含多个检查,工具中还有其他类别。要获取完整的、最新的检查列表及其详细描述,请参考官方Clang-Tidy文档1或在系统上使用clang-tidy
-list-checks命令。

学习了如何构建和使用clang-tidy之后,现在是时候更深入地了解其内部设计了。

  1. LLVM Community. Extra Clang Tools documentation: Clang-Tidy. 2024.
    URL https://clang.llvm.org/extra/clang-tidy/


发布者: 作者: 转发
评论区 (0)
U