C++静态代码检查工具 - cppcheck

简介

Cppcheck是一个用于C/C++代码的静态分析工具,它可以帮助开发者检测代码中的错误。Cppcheck可以检测出许多类型的错误,包括语法错误、未使用的函数、内存泄漏、未初始化的变量等。此外,Cppcheck还支持用户自定义规则,这使得开发者可以根据自己的需求定制Cppcheck的行为。

主要选项

错误(error):这是最严重的问题,Cppcheck 100%确定这是错误。例如,数组越界,空指针解引用等。

警告(warning):Cppcheck认为代码看起来有问题,但它并不确定这是否真的是错误。例如,有可能发生整数溢出,有可能发生除以零的情况等。

样式(style):这些是关于代码风格的问题,例如未使用的函数、多余的代码等。

可移植性(portability):当代码在不同的平台上运行时可能会出现问题。例如,使用了不可移植的函数,或者依赖于编译器特定的行为。

性能(performance):Cppcheck会发出警告,如果代码可以优化以提高性能。

信息(information):这些是一些有趣的,非关键的信息,通常可以忽略。

这些选项可以通过命令行参数进行启用或禁用,以定制Cppcheck的行为。例如,如果你只关心错误和警告,你可以使用--enable=warning,error参数来运行Cppcheck。

检查范围

以下是 Cppcheck 的主要检查范围:

未定义行为:包括死指针、零除、整数溢出、无效的位移操作数、无效的转换、STL的无效使用、内存管理、空指针解引用、越界检查、未初始化的变量、写入const数据等。

安全性:Cppcheck 可以检测到一些常见的安全漏洞,如缓冲区错误、不当的访问控制、信息泄露等。

编码标准:Cppcheck 支持多种编码标准,包括 Misra C 2012、Misra C++ 2008、Cert C、Cert C++ 等。

其他检查:Cppcheck 还有许多其他的检查,具体可以参考 这个链接 https://sourceforge.net/p/cppcheck/wiki/ListOfChecks/

开启/关闭检查器

Cppcheck允许你通过命令行参数来启用或禁用特定的检查器。你可以使用--enable=参数来启用特定的检查器,或者使用--disable=参数来禁用特定的检查器。

例如,如果你只想启用内存相关的检查,你可以使用以下命令:

cppcheck --enable=warning,performance,portability,information,missingInclude --suppress=missingIncludeSystem yourfile.cpp

这个命令将启用所有的警告,性能,可移植性,信息和缺失包含的检查,但是会抑制系统缺失包含的警告。

你可以在Cppcheck的官方手册中找到更多关于如何使用这些参数的信息。手册中详细介绍了每个参数的用途和如何使用它们。

请注意,你需要根据你的需求来选择启用或禁用哪些检查器。不是所有的检查器都适合所有的情况,所以你需要根据你的代码和你想要检查的问题来选择合适的检查器。

获取检查器列表

cppcheck --doc

获取错误消息列表

cppcheck --errorlist

内存泄漏相关检查

在Cppcheck中,内存泄漏检查是默认启用的。这意味着,即使你没有指定任何参数,Cppcheck也会检查内存泄漏。这是因为内存泄漏是一种严重的问题,所以Cppcheck默认总是检查它。

Cppcheck是一个静态分析工具,它可以检查C/C++代码中的多种类型的内存泄漏,包括但不限于:

未释放的内存:当程序使用malloc、calloc、realloc或new分配内存,但没有使用free或delete释放它时,会发生内存泄漏。

未关闭的文件:当程序使用fopen或其他函数打开文件,但没有使用fclose关闭它时,会发生资源泄漏,这也可以看作是一种特殊的内存泄漏。

未释放的系统资源:当程序使用系统API分配资源(例如,使用socket函数创建套接字),但没有使用相应的函数释放它时,会发生资源泄漏。

然而,Cppcheck作为一个静态分析工具,它的检查是基于源代码的,而不是基于程序的运行状态。这意味着它有一些局限性:

动态行为:Cppcheck可能无法准确地检测出由于程序的动态行为(例如,条件分支、循环、递归、并发等)导致的内存泄漏。

复杂的数据结构:如果程序使用了复杂的数据结构(例如,链表、树、图等),并且内存管理逻辑也很复杂,Cppcheck可能无法准确地检测出内存泄漏。

间接的内存泄漏:如果内存泄漏是通过间接的方式发生的(例如,通过函数指针、虚函数、回调函数等),Cppcheck可能无法检测出它

外部库和系统API:如果内存泄漏是由于错误使用外部库或系统API导致的,Cppcheck可能无法检测出它,除非这些库和API已经被Cppcheck的开发者显式地支持。

因此,虽然Cppcheck是一个非常有用的工具,但它不能替代其他类型的内存泄漏检查工具和技术,例如动态分析工具(如Valgrind)、代码审查、测试等。

性能相关

Cppcheck可以检查一些性能相关的问题。你可以通过以下命令来启用性能相关的检查:

cppcheck --enable=performance yourfile.cpp

这个命令将启用性能相关的检查,不会启用其他的检查器。

性能检查可以帮助你找到可能影响代码运行效率的问题,例如未使用的变量,未使用的函数返回值,以及可能导致性能下降的编程模式等。

Cppcheck是一个静态分析工具,它可以检查C/C++代码中的各种问题,包括性能问题。以下是Cppcheck可以检查的一些性能问题类别:

未使用的函数:如果代码中有未使用的函数,这可能会浪费内存和CPU资源。

未使用的变量:同样,未使用的变量也可能会浪费内存。

过度复杂的函数:如果一个函数过于复杂,它可能会导致CPU使用率过高。

过大的栈使用:如果一个函数使用了过多的栈内存,这可能会导致栈溢出,从而导致程序崩溃。

过度的循环:如果一个循环运行的次数过多,或者循环中的代码过于复杂,这可能会导致性能问题。

然而,Cppcheck的性能检查也有其局限性。以下是一些主要的局限性:

静态分析的局限性:Cppcheck是一个静态分析工具,它只能检查代码的静态特性,不能检查运行时的性能问题 。例如,它不能检查内存泄漏、CPU使用率过高、磁盘I/O过多等运行时的性能问题。

不能检查算法效率:Cppcheck不能检查代码中使用的算法的效率。例如,如果你使用了一个O(n^2)的算法,而有一个O(n log n)的算法可以完成同样的任务,Cppcheck无法检测这个问题。

不能检查并发问题:Cppcheck不能检查并发问题,例如死锁、竞态条件等 。这些问题通常需要动态分析工具或专门的并发分析工具来检查。

如果你需要进行深入的性能分析,你可能需要使用专门的性能分析工具,如gprofValgrindCallgrind ,或者Intel VTune等。

安装

通过下载源码包安装, 比如2.12 版本:

1.登录http://cppcheck.net/ 下载2.12版本souce code并解压

2.cd cppcheck-2.12 && mkdir build && cd build

  1. cmake ...

可能报错,需要安装 cmake/extra-cmake-modules

  1. make -j8

5.添加如下命令到/etc/profile

export CPPCHECK_HOME=/home/chenjp11/env_profile/cppcheck/cppcheck-2.10/build/bin

export PATH= P A T H : PATH: PATH:CPPCHECK_HOME

source /etc/profile使其生效

直接执行cppcheck 即可

简单使用

1. 多线程检查

选项 -j 用于指定需要使用的线程数,例如,使用 4 个线程检查文件夹中的文件:

cppcheck -j 4 path

  1. 可以对单个项目文件(.vcxproj)或整个解决方案(.sln)运行 Cppcheck。

在整个解决方案上运行 cppcheck:cppcheck --project=xxx.sln

e.g.

cppcheck .

cppcheck -j4 --enable=all --template=vs --inconclusive .

cppcheck -j4 --enable=all --xml --xml-version=2 --inconclusive .

cppcheck -j4 --enable=all --template="{file}, {line}, {severity},{id},{message}" --inconclusive .

Tips:

检查qt代码会报关于qt的宏定义找不到的错误,需要加上参数 --library=qt。 e.g., cppcheck --library=qt -j8 .

相关推荐
捕鲸叉4 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer4 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq4 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
青花瓷5 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
幺零九零零6 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
捕鲸叉7 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
一个通信老学姐7 小时前
专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节
Dola_Pan7 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法
yanlou2338 小时前
KMP算法,next数组详解(c++)
开发语言·c++·kmp算法
小林熬夜学编程8 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法