使用 Clang-Tidy 进行C++静态代码分析:一个完整的配置实例

文章目录

  • 使用 Clang-Tidy 进行静态代码分析:一个完整的配置实例
    • 0. Clang-Tidy简介
    • 1. 安装 Clang-Tidy
    • 2. 配置 `.clang-tidy`
    • 3. 检查项详解
      • 3.1 静态分析器(Static Analyzer)
      • 3.2 现代化(Modernize)
      • 3.3 Google 代码风格(Google)
      • 3.4 可读性(Readability)
      • 3.5 CERT 安全编码标准(CERT)
      • 3.6 Bug 检测(Bugprone)
      • 3.7 C++ 核心指南(CppCoreGuidelines)
      • 3.8 杂项(Miscellaneous)
    • 4. 使用 Clang-Tidy
      • 4.1 生成 `compile_commands.json`
      • 4.2 运行检测
      • 4.3 执行结果
    • 5. 资源阅读

使用 Clang-Tidy 进行静态代码分析:一个完整的配置实例

0. Clang-Tidy简介

Clang-Tidy 是一款功能强大的静态代码分析工具,用于检测 C++ 代码中的潜在问题和改进建议。它基于 LLVM/Clang 框架构建,能够深入理解代码结构和语义,并提供高精度的检测结果。

Clang-Tidy 是一个基于 LLVM/Clang 的代码分析工具,通过解析代码生成抽象语法树(AST),深入理解代码结构和语义,从而进行静态代码分析。AST 是一种树状数据结构,代表了程序的语法结构。Clang-Tidy 利用这个结构来检测代码中潜在的问题和改进的建议。

1. 安装 Clang-Tidy

要安装最新版本的 Clang-Tidy,推荐使用 llvm.sh 脚本,直接apt-get安装后的clang-tidy版本较旧。

  • 先使用 llvm.sh 脚本:
  1. 下载并运行 llvm.sh 脚本来安装 LLVM 和 Clang-Tidy:

    wget https://apt.llvm.org/llvm.sh
    chmod +x llvm.sh
    sudo ./llvm.sh 18  # 安装了18版本
    
  2. 接着使用 apt-get 安装 Clang-Tidy:

    sudo apt-get install clang-tidy
    

2. 配置 .clang-tidy

本次配置比较详细,主要是为了减少误报。

---
Checks: '-*,clang-analyzer-core.*,clang-analyzer-cplusplus.*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-equals-default,modernize-use-nullptr,modernize-use-override,google-explicit-constructor,google-readability-casting,readability-braces-around-statements,readability-identifier-naming.ClassCase,readability-identifier-naming.StructCase,readability-identifier-naming.TypedefCase,readability-identifier-naming.EnumCase,readability-non-const-parameter,cert-dcl21-cpp,bugprone-undelegated-constructor,bugprone-macro-parentheses,bugprone-macro-repeated-side-effects,bugprone-forward-declaration-namespace,bugprone-bool-pointer-implicit-conversion,bugprone-misplaced-widening-cast,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-reinterpret-cast,misc-unconventional-assign-operator'
WarningsAsErrors: ''
HeaderFilterRegex: ''
CheckOptions:# 现代化(Modernize)- key:             modernize-redundant-void-argvalue:           'true'  # 检查并移除函数声明中冗余的 void 参数。- key:             modernize-use-bool-literalsvalue:           'true'  # 建议使用布尔字面量 true 和 false 代替整数值 0 和 1。- key:             modernize-use-equals-defaultvalue:           'true'  # 建议在默认构造函数、复制构造函数和赋值运算符中使用 = default,以简化代码。- key:             modernize-use-nullptrvalue:           'true'  # 建议使用 nullptr 代替 NULL 或 0 来表示空指针。- key:             modernize-use-overridevalue:           'true'  # 建议在覆盖基类虚函数时使用 override 关键字,以增加代码的清晰性和安全性。# Google 代码风格(Google)- key:             google-explicit-constructorvalue:           'true'  # 检查并建议在单参数构造函数中使用 explicit 关键字,以防止隐式转换。- key:             google-readability-castingvalue:           'true'  # 检查并建议使用 C++ 风格的类型转换(如 static_cast、dynamic_cast、const_cast 和 reinterpret_cast)代替 C 风格的类型转换。# 可读性(Readability)- key:             readability-braces-around-statementsvalue:           'true'  # 建议在单行语句周围添加大括号,以提高代码的可读性和一致性。- key:             readability-identifier-naming.ClassCasevalue:           'CamelCase'  # 类名应使用 CamelCase 风格,例如 MyClassName。- key:             readability-identifier-naming.StructCasevalue:           'CamelCase'  # 结构体名应使用 CamelCase 风格,例如 MyStructName。- key:             readability-identifier-naming.TypedefCasevalue:           'CamelCase'  # 类型定义应使用 CamelCase 风格,例如 MyTypeDef。- key:             readability-identifier-naming.EnumCasevalue:           'CamelCase'  # 枚举名应使用 CamelCase 风格,例如 MyEnumName。- key:             readability-non-const-parametervalue:           'true'  # 检查并标识非 const 参数,以提高代码的可读性和安全性。# CERT 安全编码标准(CERT)- key:             cert-dcl21-cppvalue:           'true'  # 检查并标识在头文件中不应包含无命名空间的 using 声明和指令,以防止命名空间污染。# Bug 检测(Bugprone)- key:             bugprone-undelegated-constructorvalue:           'true'  # 检查并标识未委托的构造函数,以确保构造函数的正确性。- key:             bugprone-macro-parenthesesvalue:           'true'  # 检查并建议在宏定义中使用括号,以防止潜在的错误。- key:             bugprone-macro-repeated-side-effectsvalue:           'true'  # 检查并标识宏中重复的副作用,以防止潜在的错误。- key:             bugprone-forward-declaration-namespacevalue:           'true'  # 检查并标识命名空间前向声明的潜在问题。- key:             bugprone-bool-pointer-implicit-conversionvalue:           'true'  # 检查并标识布尔指针的隐式转换,以防止潜在的错误。- key:             bugprone-misplaced-widening-castvalue:           'true'  # 检查并标识错误的宽化转换,以防止潜在的错误。# C++ 核心指南(CppCoreGuidelines)- key:             cppcoreguidelines-narrowing-conversionsvalue:           'true'  # 检查并标识可能导致数据丢失的窄化转换。- key:             cppcoreguidelines-pro-type-reinterpret-castvalue:           'true'  # 检查并警告使用 reinterpret_cast 的地方,以提高代码的类型安全性。# 杂项(Miscellaneous)- key:             misc-unconventional-assign-operatorvalue:           'true'  # 检查并标识不常见的赋值操作符重载,以确保代码的一致性和可维护性。
...

-*: 禁用所有默认的检查。

3. 检查项详解

3.1 静态分析器(Static Analyzer)

  1. clang-analyzer-core.*:
    • 用于检测代码中的基本问题,包括内存管理错误、未初始化变量、空指针引用等。这些检查器会深入分析代码逻辑,找出潜在的错误。
    • 主要功能
      • 检查未初始化变量使用。
      • 检查空指针解引用。
      • 检查内存泄漏。
      • 检查未处理的返回值。
      • 检查资源泄漏。
  2. clang-analyzer-cplusplus.*:
    • 专注于 C++ 代码中的特定问题。这些检查器可以检测 C++ 特有的错误,如对象的生命周期管理、构造函数和析构函数的使用等。
    • 主要功能
      • 检查 C++ 对象的正确构造和析构。
      • 检查对象的移动和复制语义。
      • 检查异常安全性。
      • 检查智能指针的正确使用。

3.2 现代化(Modernize)

  1. modernize-redundant-void-arg:
    • 检查并移除函数声明中冗余的 void 参数。使函数签名更简洁。
  2. modernize-use-bool-literals:
    • 建议使用布尔字面量 truefalse 代替整数值 01。提高代码的可读性和表达性。
  3. modernize-use-equals-default:
    • 建议在默认构造函数、复制构造函数和赋值运算符中使用 = default,以简化代码,并确保编译器生成更高效的代码。
  4. modernize-use-nullptr:
    • 建议使用 nullptr 代替 NULL0 来表示空指针。避免类型不匹配的风险。
  5. modernize-use-override:
    • 建议在覆盖基类虚函数时使用 override 关键字。确保函数覆盖的正确性,避免意外的函数隐藏。

3.3 Google 代码风格(Google)

  1. google-explicit-constructor:
    • 检查并建议在单参数构造函数中使用 explicit 关键字。防止隐式转换带来的意外行为。
  2. google-readability-casting:
    • 检查并建议使用 C++ 风格的类型转换(如 static_castdynamic_castconst_castreinterpret_cast)代替 C 风格的类型转换。提高类型转换的安全性和可读性。

3.4 可读性(Readability)

  1. readability-braces-around-statements:
    • 建议在单行语句周围添加大括号。提高代码的可读性和一致性,防止因省略大括号导致的错误。
  2. readability-identifier-naming.ClassCase:
    • 类名应使用 CamelCase 风格,例如 MyClassName。提高代码命名的一致性和规范性。
  3. readability-identifier-naming.StructCase:
    • 结构体名应使用 CamelCase 风格,例如 MyStructName。统一结构体的命名风格。
  4. readability-identifier-naming.TypedefCase:
    • 类型定义应使用 CamelCase 风格,例如 MyTypeDef。规范类型定义的命名方式。
  5. readability-identifier-naming.EnumCase:
    • 枚举名应使用 CamelCase 风格,例如 MyEnumName。保持枚举命名的一致性。
  6. readability-non-const-parameter:
    • 检查并标识非 const 参数。提高代码的可读性和安全性,防止意外修改参数值。

3.5 CERT 安全编码标准(CERT)

  1. cert-dcl21-cpp:

    • 检查并标识在头文件中不应包含无命名空间的 using 声明和指令。防止命名空间污染,提高代码的可维护性。

3.6 Bug 检测(Bugprone)

  1. bugprone-undelegated-constructor:
    • 检查并标识未委托的构造函数。确保构造函数的正确性,避免重复代码。
  2. bugprone-macro-parentheses:
    • 检查并建议在宏定义中使用括号。防止宏扩展带来的优先级问题。
  3. bugprone-macro-repeated-side-effects:
    • 检查并标识宏中重复的副作用。防止宏多次展开时的副作用问题。
  4. bugprone-forward-declaration-namespace:
    • 检查并标识命名空间前向声明的潜在问题。确保命名空间前向声明的正确性。
  5. bugprone-bool-pointer-implicit-conversion:
    • 检查并标识布尔指针的隐式转换。防止隐式转换带来的潜在错误。
  6. bugprone-misplaced-widening-cast:
    • 检查并标识错误的宽化转换。避免由于类型转换导致的数据丢失或错误。

3.7 C++ 核心指南(CppCoreGuidelines)

  1. cppcoreguidelines-narrowing-conversions:
    • 检查并标识可能导致数据丢失的窄化转换。确保类型转换的安全性,防止数据丢失。
  2. cppcoreguidelines-pro-type-reinterpret-cast:
    • 检查并警告使用 reinterpret_cast 的地方。提高代码的类型安全性,避免使用不安全的类型转换。

3.8 杂项(Miscellaneous)

  1. misc-unconventional-assign-operator:
  • 检查并标识不常见的赋值操作符重载。确保代码的一致性和可维护性,防止意外的行为。

4. 使用 Clang-Tidy

4.1 生成 compile_commands.json

使用 CMake 时,可以这样生成包含编译命令的 JSON 文件,该文件包含项目中所有源文件的编译信息。

mkdir build
cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

4.2 运行检测

有了 compile_commands.json,就可以使用run-clang-tidy或者clang-tidy检测指定源文件:
推荐使用 run-clang-tidy, 例如

run-clang-tidy -p build -config-file=./.clang-tidy

.clang-tidy 配置文件也可以不用手动指定。

  • run-clang-tidy 和 clang-tidy 的区别

    • clang-tidy:单独检测一个源文件,主要用于小规模或单文件测试。

    • run-clang-tidy:可以批量检测多个源文件,非常适用于大规模项目。

  • **是否添加 -extra-arg=-std=c++11 **
    添加 -extra-arg=-std=c++11 参数可以指定 C++ 标准版本。例如:

clang-tidy -p build -config-file=./.clang-tidy -extra-arg=-std=c++11 <source_file>

4.3 执行结果

.....
clang-tidy-18 -extra-arg=-std=c++11 -p=. --config-file=./.clang-tidy /home/test/clang-tidy/example.cpp
/home/test/Desktop/memory_analysis_v2/example.cpp:33:21: warning: narrowing conversion from 'size_t' (aka 'unsigned long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]33 |       arrayPtr[i] = i;|                     ^
830 warnings generated.
.....

5. 资源阅读

  • 官方文档:Clang-Tidy Documentation
  • 社区论坛:LLVM Discussion Forums

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/24593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

调用华为API实现语音合成

目录 1.作者介绍2.华为云语音合成2.1 语音合成介绍2.2 华为语音合成服务2.3 应用场景 3. 实验过程以及结果3.1 获取API密钥3.2 调用语音合成算法API3.3 实验代码3.4 运行结果 1.作者介绍 袁斌&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2023级研究生 研究…

SpringBoot整合Skywalking

下载Java Agent 官网&#xff1a;https://skywalking.apache.org/downloads/ 提示&#xff1a;Agent最好到网上找一找之前的版本&#xff0c;新版本可能有bug&#xff0c;如果出现了并且网上也几乎没有这个版本的解决方法那么就切换之前的版本 本地启动时 -javaagent:d:\opt\…

建筑特种工高处作业吊篮安装拆卸工题库

1、施工现场外租吊篮设备&#xff0c;在施工前应由( )编制专项施工方案&#xff0c;并由( )技术负责人和现场总监理工程师签字后实行。 A 使用单位 使用单位 B 使用单位 租赁单位 C 租赁单位 使用单位 D 租赁单位 租赁单位 2、施工现场外租吊篮…

java基础语法整理 ----- 上

java基础语法 一、变量二、数据类型三、标识符四、键盘录入五、判断语句1. 三种格式2. 练习题 六、switch语句七、循环八、循环控制语句九、方法 一、变量 1.什么是变量&#xff1a; 在程序运行过程中&#xff0c;其值可以发生改变的量从本质上讲&#xff0c;变量是内存中的一…

[C++] 小游戏 斗破苍穹 2.2.1至2.11.5所有版本(中) zty出品

目录 2.8.2 2.9.1 2.10.1 2.10.2 2.10.3 2.10.4 2.10.5 2.8.2 #include<stdio.h> #include<iostream> #include<ctime> #include<bits/stdc.h> #include<time.h> //suiji #include<windows.h> //SLEEP函数 using namespace std; st…

axios的基本使用

axios 是一个功能强大且易于使用的 HTTP 客户端库&#xff0c;提供了丰富的功能和配置选项。以下是 axios 的完整使用示例&#xff1a; 发送 GET 请求&#xff1a; axios.get(https://jsonplaceholder.typicode.com/posts).then(response > {console.log(response.data);}…

MineAdmin 前端打包后,访问速度慢原因及优化

前言&#xff1a;打包mineadmin-vue前端后&#xff0c;访问速度很慢&#xff0c;打开控制台&#xff0c;发现有一个index-xxx.js文件达7M&#xff0c;加载时间太长&#xff1b; 优化&#xff1a; 一&#xff1a;使用文件压缩&#xff08;gzip压缩&#xff09; 1、安装compre…

360数字安全:2024年3月勒索软件流行态势分析报告

勒索软件传播至今&#xff0c;360 反勒索服务已累计接收到数万勒索软件感染求助。随着新型勒索软件的快速蔓延&#xff0c;企业数据泄露风险不断上升&#xff0c;勒索金额在数百万到近亿美元的勒索案件不断出现。勒索软件给企业和个人带来的影响范围越来越广&#xff0c;危害性…

java基础练习题

1、一个".java"源文件中是否可以包括多个类&#xff1f;有什么限制&#xff1f; 可以包含多个类。但是只有一个类可以声明为public&#xff0c;且要求声明为public的类的类名与源文件名相同。 2、java的优势&#xff1f; a、跨平台性 b、安全性高 c、简单性 d、…

无延迟,持续畅玩 - Wi-Fi 6 助力打造游戏厅极致体验

1、需求背景&#xff1a; 连锁游戏厅行业竞争激烈&#xff0c;顾客对高品质的游戏体验有着高要求。网络是游戏厅的核心基础设施之一&#xff0c;需要确保游戏过程中的网络连接稳定性和顾客满意度。 长时间稳定连接 为保证顾客的游戏体验感&#xff0c;游戏厅要确保网络连接长…

介绍建造者模式

建造者模式 将一个复杂对象的创建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示 四种角色 Product 产品角色 指的是一个具体的产品对象Builder 抽象建造者 创建一个产品对象的各个部件的接口/抽象类ConcreteBuilder 具体建造者 实现或继承抽象建造者接口…

Python量化交易学习——Part6:多因子选股策略实战(1)

在上一节中,我们学习了基于IC值的多因子计算方法,说白了就是先选择我们认为与股票收益率影响大的因子(如市盈率、净资产收益率、净利润增长率等),之后计算各个因子与股票收益率之间的相关系数,选择相关系数大的因子进行加权得到新的因子,之后求得新因子与收益率之间的相…

Leetcode:删除链表的倒数第N个结点

题目链接&#xff1a;19. 删除链表的倒数第 N 个结点 - 力扣&#xff08;LeetCode&#xff09; 普通版本&#xff08;统计结点 头删 中间删除&#xff09; 主旨&#xff1a;对于链表的删除要考虑头删和尾删的结果 /*** Definition for singly-linked list.* struct ListNo…

使用 CloudFlare Turnstile 解决跨境电商站的垃圾邮件侵扰

最近明月一个跨境电商代维客户的网站被垃圾邮件侵扰了,从最开始的每天几封疯狂到每天几百上千封垃圾邮件,几乎所有可拦截屏蔽的关键词都是随机可变的,简单的邮件客户端拦截基本已经没有任何效果了,在收到用户的求助后经过分析发现主要是利用网站在线咨询页面里的邮件发送造…

SMS-GSM

SMS-GSM 短信模块&#xff0c;不想通过第三方的接口&#xff0c;自己搭建短信模块&#xff0c;提高信息安全。 /**/ package sms;import com.diagcn.smslib.CMessage; import com.diagcn.smslib.COutgoingMessage; import com.diagcn.smslib.SZHTOCService;/*** 短信模块** au…

汇编:头文件

汇编头文件&#xff08;header files&#xff09;在汇编语言编程中类似于高层语言中的头文件&#xff0c;它们通常包含宏定义、常量定义、数据结构定义、函数声明以及其他在多个汇编源文件中共享的代码&#xff1b;使用头文件可以提高代码的可维护性和可读性&#xff0c;并使代…

【全开源】云调查考试问卷系统(FastAdmin+ThinkPHP+Uniapp)

便捷、高效的在线调研与考试新选择​ 云调查考试问卷是一款基于FastAdminThinkPHPUniapp开发的问卷调查考试软件&#xff0c;可以自由让每一个用户自由发起调查问卷、考试问卷。发布的问卷允许控制问卷的搜集、回答等各个环节的设置&#xff0c;同时支持系统模板问卷&#xff…

11、架构-从类库到服务之客户端负载均衡

目录 主要概念 客户端负载均衡的定义与重要性 历史背景 技术细节 客户端负载均衡的实现方式 工作原理 常见的客户端负载均衡策略 实际应用 Netflix Ribbon Spring Cloud LoadBalancer 服务网格&#xff08;Service Mesh&#xff09; 代理负载均衡器 工作原理 优点…

Android UI:Drawable:DrawableContainer

文章目录 定义API 类操作源码分析 ImageView.setImageLevel选择LevelListDrawable中的DrawableDrawableContainer封装Drawable[]数组AnimationScaleListDrawable.start总结定义 DrawableContainer封装一组Drawable,不同的DrawableContainer实现Drawable不同的展示方式 API …

linux内存缓存占用过高分析和优化

1、什么是buffer/cache &#xff1f; buffer/cache其实是作为服务器系统的文件数据缓存使用的&#xff0c;尤其是针对进程对文件存在read/write操作的时候&#xff0c;所以当你的服务进程在对文件进行读写的时候&#xff0c;Linux内核为了提高服务的读写速度&#xff0c;则将会…