C/C++代码静态检测工具PC-Lint常见错误总结

目录

1、PC-Lint 概述

2、PC-lint 常见错误列举

3、PC-Lint报告的语法错误

4、总结


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html       为了提高代码质量,我们一般会引入一些代码静态检测工具,比如PC-lint和腾讯的TScanCode等,可以帮我们发现代码中存在的一些潜在问题。之前我们项目中使用了PC-Lint,本文大概地总结一个PC-Lint的常报错误,以及这些错误的解决办法。

1、PC-Lint 概述

       PC-Lint是一种C/C++静态代码检测工具,通过扫描静态的代码文件(头文件和源文件)进行分析,不仅可以像IDE编译器那样检查出一般的语法错误,还可以检查出那些表面上完全合乎语法要求,但很可能是潜在的、不易发现的问题或错误,比如数组访问越界、内存泄漏、使用未初始化变量等,这样就可以很好地提高软件的质量。

       对于这些bug,如果事先没有检测,在软件运行过程中出了问题,通过走读代码或者使用分析工具去分析,可能会花费很长时间才能找到原因。通过使用PC-Lint进行检测,可以在测试开始前就能检测出这些错误,会给测试和开发节省很多的时间。虽然使用PC-Lint会花费一些时间,但这是完全值得的。

       另外,PC-lint还支持Effective C++ / More Effective C++中说描述的各种提高效率和防止错误的方法,对照相应的条款,还可以学习与熟悉这些编程要点,提升我们编码的技能。

2、PC-lint 常见错误列举

       下面所列举的常见错误只有ID号与简单的描述信息,如果有需要,可以通过ID号在PC-Lint目录下的MsgRef.html文件中查看详细的描述信息。另外本文对这些错误只进行了一些简单的分析,其中部分错误可以参见《Effective C++》上相应的条款。

1)error 1561: (Warning -- Reference initialization causes loss of const/volatile integrity (arg. no. 1))

        PC-Lint发出警告:“第一个参数在初始化时会破坏const属性”,双击警告,定位到代码:

TManufacturerInfo *pManufactureList=NULL;
DWORD dwManufactureNum=g_pcCommData->GetAllManufactory(pManufactureList);

查看一下GetAllManufactory函数的声明:

DWORD GetAllManufactory(const TManufacturerInfo*& ptManufactory) const;

参数是const TManufacturerInfo*&,不希望指针所指向的内容被改变,但是我们传入的参数是TManufacturerInfo *,缺少了const限制,导致我们就可以随意改变指针所指向的内容。 

2)error 1401: (Warning -- member ‘XXX::YYY' not initialized by constructor);

        成员变量没有被初始化,会造成程序一些不可预知的结果,对于这些危害,大家都比较清楚的,但这还是最常犯的一些错误之一,因为大家在开始写代码的时候或以后的维护的时候还会忘记的。

3)error 1729: (Initializer inversion detected for member 'Symbol' );

       成员变量在初始化列表的顺序与在类声明中出现的顺序不一致。C++总是按成员变量在类声明中出现的顺序来初始化成员变量的,如果不一致有可能造成一些隐蔽的bug;例如下面的代码:

class A
{
public:A( ):y(100),x(y){}
private:int x;int y;
};

在成员变量初始化时,由于y(100)写在了x(y)之前,我们很可能认为先执行y(100),然后执行x(y),这样x与y的值都初始化为100,但实际上x(y)首先执行,y这时还没有被初始化,x就被初始化为一个随机值。

4)error 1540: (Warning -- Pointer member ' XXX::YYY ' neither freed nor zeroed by destructor -- Effective C++ #6)

       在析构函数中一定要把成员指针变量置为空指针,以免产生野指针,并且查看程序中是否有申请空间的操作,如果有一定要用delete或delete[]释放空间,如果没有则一定不要释放该指针指向的空间,把别人申请的空间释放掉,很可能引起错误。

5)error 545: (Warning -- Suspicious use of &)

       意思是“错误的使用了&”,定位到代码:

int array[100];
memset(&array, 0, sizeof(array));

原来我们多用了“&”, 改成:

memset(array, 0, sizeof(array));

就行了。其实array与&array都指向了同一个地址,但是要注意 array 和 &array 的类型是不同的。array 相当于 &array[0],而 &array 是一个指向 int[100] 的指针,类型是 int(*)[100]。array + 1指向数组的第二个元素,而&array + 1指向的地址已经超出了本数组的地址范围了。

6)error 616: (Warning -- control flows into case/default)
error 744: (Info -- switch statement has no default)
error 788:(Info -- enum constant 'Symbol' not used within defaulted switch)

       这3个警告都是与switch语句有关,都是在使用switch时最容易犯的错误,第一个是当一个case语句后面没有用break,程序会继续执行下一个case语句;第二个是没有写default语句;第三个是当使用enum类型作为switch值时,至少有一个enum变量没有出现在case语句中。

7)error 613: (Warning -- Possible use of null pointer ' 'XXX::YYY ' in left argument to operator '->')

       指针有可能为空,使用空指针会使程序崩溃的,在写代码时遇到使用指针时最好还是用if语句判断一下,或者assert断言一下。

8)error 1763: (Info -- Member function 'CXXX::YYY(void) const marked as const indirectly modifies class)

       成员函数被声明成const,但是成员变量的值有可能被间接改变,看一下函数的实现:

HTREEITEM CMGTreeCtrl::GetHitItem() const
{return m_TvhitLastClick.hItem;
}

函数被声明成const,表示这个函数不能改变成员变量的值,但当函数返回成员变量的指针或句柄时,成员变量的值就能被外部操作改变,这时要为返回值加上const,以便告诉调用者,不希望返回的指针或句柄所指向的内容的被改变。

9)error 773: (Info -- Expression-like macro 'LIST_DEVICE_MSG_ON_PAGE_CHANGE' not parenthesized)

       定位到代码:

#define LIST_DEVICE_MSG_ON_PAGE_CHANGE     WM_USER+1

定义宏时没有加括号,当程序预编译时,用WM_USER+1替换到代码中有可能产生非预期的结果,比如:

LIST_DEVICE_MSG_ON_PAGE_CHANGE - LIST_DEVICE_MSG_ON_PAGE_CHANGE

我们当然希望结果是0,但得到的结果却是2。

10)error 424: (Warning -- Inappropriate deallocation (delete) for 'new[]' data -- Effective C++ #5)

       使用new[]申请空间,但却使用delete释放空间,造成内存的泄漏,在使用时new与delete配对,new[]与delete[]配对。

11)error 1506: (Warning -- Call to virtual function ' 'XXX::YYY(void)' within a constructor or destructor)

       在构造函数或者析构函数中千万不要调用virtual函数,因为在base class构造函数中,virtual函数不会调用derived class中的虚函数,不会带来你所预想的结果。如果一定要使用virtual函数,请使用“类名::virtual函数”表示调用自身的函数,避免造成误解。

12)error 527:(Warning -- Unreachable code at token 'XX')

       不可到达的代码。可能是因为前面return掉了,后面的代码就永远不可能执行。通常是因为我们暂时屏蔽掉了某些功能但暂时没有删除其代码导致。可以用#if 0 来屏蔽之:

#if 0 //写出屏蔽原因
代码 
#endif

13)error 1925:(Note -- Symbol 'XXX::YYY' is a public data member) 
error 1536:(Warning -- Exposing low access member 'CXXX::m_XX') 

       在类设计时应该将所有成员变量为private,而不是public,因为:

(1)更精确的控制对成员变量的处理。如果成员变量是public的话,每个人都可以读写它,但如果时private的话,我们就可以通过是否提供setterXX、getterXX实现对成员变量的不准访问,只读,只写,读写多种方式。

(2)封装性,将成员变量隐藏在函数接口的背后,为以后修改接口提供方便。

14)error 578: (Warning -- Declaration of symbol ' XXX ' hides symbol ' XXX' (line 891))

       当前声明的XXX覆盖了891行声明的XXX,在一个变量的作用域下再次声明了一个同名的变量在语法上当然没有什么错误,但是这样会造成歧异,容易混淆,给别人阅读代码造成困难,不利于以后的维护。

15)error 661: (Warning -- Possible access of out-of-bounds pointer (22 beyond end of data) by operator '[')

        数组下标可能越界。

16)error 774: (Info -- Boolean within 'if' always evaluates to False)

        If判断语句的值始终为FALSE或者TRUE。

17)error 524: (Warning -- Loss of precision (arg. no. 3) (double to int))
error 732: (Info -- Loss of sign (arg. no. 1) (char to unsigned int))
error 713: (Info -- Loss of precision (arg. no. 1) (unsigned long to long))
error 573: (Warning -- Signed-unsigned mix with divide)
error 574: (Warning -- Signed-unsigned mix with relational)
error 747: (Info -- Significant prototype coercion unsigned long to double)
error 737: (Info -- Loss of sign in promotion from int to unsigned long)
error 734: (Info -- Loss of precision (arg. no. 2) (31 bits to 7 bits))
error 570: (Warning -- Loss of sign (initialization) (int to unsigned long))
error 569: (Warning -- Loss of information (assignment) (32 bits to 31 bits))
error 736: (Info -- Loss of precision (initialization) (55 bits to 32 bits))

       与精度丢失和符号错误相关的一些警告。

18)error 539: (Warning -- Did not expect positive indentation from line 529)

        代码格式没有对齐,这个时候,先选中没有对齐的代码,然后使用“ALT+F8”键,就可以对齐了。

19)error 715 (Symbol XXX not referenced)
error 752 (local declarator XXX not referenced)
error 550 (Symbol XXX  not accessed)
error 529 (Symbol XXX not subsequently referenced)
error 750    (Info -- local declarator 'XXX' macor not referenced)
error 751    (Info -- local typedef 'XXX' not referenced)

代码中声明了一些没有用过的东东。

20)error 685: (Warning -- Relational operator '>=' always evaluates to True)
error 775: (Info -- non-negative quantity cannot be less than zero)
error 568: (Warning -- non-negative quantity is never less than zero)

      if 语句中判断一个整数是否小于零, 而正数不可能小于零:

DWORD dwValue = XXX;
if( dwValue >= 0 )
if( dwValue < 0 )

21)其他错误

       以下的警告信息也是比较常见的信息,这里只做一些简单的列举:

error 818: (Info -- Pointer parameter 'Symbol' (Location) could be declared as pointing to const)//建议为指针参数加上const属性
error 1762: (Info -- Member function 'Symbol' could be made const)//建议为成员函数加上const属性
error 1746: (Info -- parameter could be made const reference)// 函数参数可以成为const引用
error 1764: (Info -- Reference parameter 'XX'  could be declared const ref) //建议为引用参数加上const属性

error 1732: (Info -- new in constructor for class 'CXXX' which has no assignment operator)//在类的构造函数中使用new申请了一块内存,但没有提供operator =。
error 1733: (Info -- new in constructor for class 'CXXX' which has no copy constructor )// 在类的构造函数中使用new申请了一块内存,但没有提供copy constructor。
注:在构造函数中使用new申请一块内存,可以推测在类中应该有一个成员变量指针指向该内存。当使用该类的一个对象去克隆另一个对象时,如果该类没有声明copy constructor或operator =,编译器将会自动生成一个默认的copy constructor或operator =,但默认的copy constructor与operator =都是“浅拷贝”,那么这2个对象的指针就指向了同一块内存地址,当一个对象析构时这块内存会被释放,另一个对象就会被破坏。

error 749: (Info -- local enumeration constant not ref)//定义了枚举常量却没有使用。
error 506: (Warning -- Constant value Boolean)//布尔值是个常量,导致if()或者while()每次都执行同样的路径。
error 669: (Warning -- Possible data overrun for function memcpy)//可能copy的数据过大
error 765: (Info -- external XXX could be made static)//只用在一个文件中的变量应当声明为static

error 429: (Warning -- Custodial pointer 'pXXX'has not been freed or returned)//内存可能没有释放 
error 1774: (Info -- Could use dynamic_cast to downcast polymorphic type 'CXXX')//建议使用dynamic_cast将一个父类转换成子类。
error 730: (Info -- Boolean argument to function)// 函数参数非 Boolean类型,但却传入了一个Boolean类型的数。
error 1551: (Warning--function may throw exception 'Name' in destructor 'Symbol' ) //析构函数抛异常

3、PC-Lint报告的语法错误

       以下列举的警告都是语法错误,基本上都是类型错误、重复定义、没有定义之类的东西,由编译器检查就OK了,不用用PC-lint来检查,一般情况下可以把这些信息屏蔽掉。

error 40: Undeclared identifier//标识符未定义
error 1055: Symbol 'XXX' undeclared, assumed to return int//函数没有定义,假定返回值为int
error 1015: Symbol 'XXX' not found in class //没有定义成员变量'XXX'
error 1013: Symbol 'XXX(OnInitialUpdate)' not a member of class 'YYY(CListView)' //'XXX’不是另一个成员函数
error 746: call to function 'XXX(IsKindOf())' not made in the presence of a prototype) //没有发现函数原型
error 38: Offset of symbol 'XXX' inconsistent (conflicts with other cpp)//    
error 113: (Error -- Inconsistent enum declaration)//枚举变量声明的顺序不一致(另一个模块有同名的枚举类型引起)
error 148: Error -- member 'Symbol' previously declared at Location//变量已经声明过了,重复声明
error 1039: (Error -- Symbol 'XX::YY()' is not a member of class 'XX')// YY()不是'XX'的成员函数
error 322: (Error -- Unable to open include file 'xx.h')//不能打开头文件
error 7: (Error -- Unable to open include file 'xx.h') //不能打开头文件
error 1074: (Error -- Expected a namespace identifier)//希望使用命名空间标识符
error 31: (Error -- Redefinition of symbol "XXX" compare with line)//重复定义 
error 14: Symbol 'XXX' previously defined//变量重复定义
error 1032: (Error -- Member 'XXX' cannot be called without object)//非static变量只能通过类的一个对象调用
error 58: (Error -- Bad type)指针不能与某个数比较 
error 63: (Error -- Expected an lvalue)//需要是一个左值
error 115: (Error -- struct/union not defined)//结构体后者枚举类型没有定义
error 770: (Info -- tag 'Symbol' defined identically at Location)//定义了相同的结构体或者联合体
error 64: type mismatch //类型不匹配
error 526: (Warning -- Symbol 'XXX'没有定义),变量没有定义
error 833: (Info -- Symbol 'XXX' is typed differently in another module)//变量在另一个模块中被定义成不同的类型
error 118: (Error -- Too few arguments )//传入的参数太少
error 55: (Error -- Bad type)//类型错误
error 1046: (Error -- Member 'CXXX::XX', referenced in a static function, requires an object)//非static变量只能不能被static函数调用

4、总结

       由于人工Code Review工作很耗精力,我们在程序进行编译测试前使用PC-lint进行代码检查,可以预先发现和规避很多错误,提高代码质量,节省测试时间,规范编码行为。

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

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

相关文章

MySQL数据库入门到精通8--进阶篇( MySQL管理)

7. MySQL管理 7.1 系统数据库 Mysql数据库安装完成后&#xff0c;自带了一下四个数据库&#xff0c;具体作用如下&#xff1a; 7.2 常用工具 7.2.1 mysql 该mysql不是指mysql服务&#xff0c;而是指mysql的客户端工具。 语法 &#xff1a; mysql [options] [database] 选…

CentOS 7系统安装与配置、常用100条操作命令

CentOS 7 是一个广泛使用的开源 Linux 操作系统&#xff0c;它是 Red Hat Enterprise Linux (RHEL) 的一个免费重建版本&#xff0c;以稳定性和安全性而著称。在 CentOS 7 上安装虚拟机通常使用虚拟化技术&#xff0c;如 VirtualBox 或 VMware 等。以下是 CentOS 7 的简要介绍以…

5请求处理流程

产品代码都给你看了&#xff0c;可别再说不会DDD&#xff08;五&#xff09;&#xff1a;请求处理流程 # 这是一个讲解DDD落地的文章系列&#xff0c;作者是《实现领域驱动设计》的译者滕云。本文章系列以一个真实的并已成功上线的软件项目——码如云&#xff08;https://www.…

java项目之课程思政元素收集遴选系统(ssm源码+文档)

项目简介 课程思政元素收集遴选系统实现了以下功能&#xff1a; 管理员&#xff1a;主页、个人中心、用户管理、教师管理、课程信息管理、课程类型管理、加入课程管理、留言板管理、论坛管理、系统管理、留言管理。教师&#xff1a;主页、个人中心、课程信息管理、课程类型管…

Python 逢七拍手小游戏1.0

"""逢七拍手游戏介绍&#xff1a;逢七拍手游戏的规则是&#xff1a;从1开始顺序数数&#xff0c;数到有7&#xff0c;或者是7的倍数时&#xff0c;就拍一手。例如&#xff1a;7、14、17......70......知识点&#xff1a;1、循环语句for2、嵌套条件语句if/elif/e…

网络上怎么赚点零花钱

现代物质社会中&#xff0c;我们常常会被琐碎的开销困扰。无论是衣食住行还是休闲娱乐&#xff0c;总有一些额外的花费&#xff0c;使我们不得不时常思索如何赚点零花钱。而现如今&#xff0c;随着互联网的飞速发展&#xff0c;我们有了更多的机会通过网络来实现这个目标。现在…

Swift SwiftUI 隐藏键盘

如果仅支持 iOS 15 及更高版本&#xff0c;则可以通过聚焦和取消聚焦来激活和关闭文本字段的键盘。 在最简单的形式中&#xff0c;这是使用 FocusState 属性包装器和 focusable() 修饰符完成的-第一个存储一个布尔值&#xff0c;用于跟踪第二个当前是否被聚焦。 Code struct C…

Jenkins学习笔记2

Jenkins下载安装&#xff1a; 从清华源开源镜像站上下载jenkins的安装包&#xff1a; 安装的是这个版本。 关于软件的版本&#xff0c;尽量使用LTS&#xff0c;长期支持。 首先是安装openjdk&#xff1a; yum install fontconfig java-11-openjdk[rootlocalhost soft]# java …

简单易上手的在windows部署cmake版paddledetection/yolo(c++)

一.下载源代码 官方地址&#xff1a; https://gitee.com/paddlepaddle/PaddleDetection 网盘&#xff1a; paddledetection 链接&#xff1a;https://pan.baidu.com/s/1g0z5SYQNDR1pwe9iAtvR3A?pwdktl6 提取码&#xff1a;ktl6 paddleocr 链接&#xff1a;https://pan.baid…

企业做问答营销的优势有哪些?媒介盒子告诉你

什么是问答营销&#xff1f;问答营销是软文营销的方式之一&#xff0c;品牌方一般会在问答平台上找出相关的问题进行回答&#xff0c;并在问答中融入自己的品牌、产品信息&#xff0c;达到推广的目的。那么企业做问答营销的优势有哪些呢&#xff1f;媒介盒子告诉你。 一、 加强…

《从菜鸟到大师之路 MySQL 篇》

《从菜鸟到大师之路 MySQL 篇》 数据库是什么 数据库管理系统&#xff0c;简称为DBMS&#xff08;Database Management System&#xff09;&#xff0c;是用来存储数据的管理系统。 DBMS 的重要性 无法多人共享数据 无法提供操作大量数据所需的格式 实现读取自动化需要编程…

SolidJs节点级响应性

前言 随着组件化、响应式、虚拟DOM等技术思想引领着前端开发的潮流&#xff0c;相关的技术框架大行其道&#xff0c;就以目前主流的Vue、React框架来说&#xff0c;它们都基于组件化、响应式、虚拟DOM等技术思想的实现&#xff0c;但是具有不同开发使用方式以及实现原理&#…

Vue的`provide`和`inject`特性:上下文传递与数据共享

Vue的provide和inject特性&#xff1a;上下文传递与数据共享 Vue.js 是一款流行的前端 JavaScript 框架&#xff0c;它提供了丰富的功能来构建可维护和可扩展的用户界面。其中&#xff0c;provide 和 inject 特性是 Vue 中的一项强大功能&#xff0c;它们允许你在父组件提供数…

客户成功体系如何构建?请看这7步

文章目录 1. 当下客户成功的痛点2. 客户成功体系构建七步法2.1 第一步&#xff1a;定义客户成功章程2.2 第二步&#xff1a;客户成功组织设置与组织绩效管理设置2.3 第三步&#xff1a;关键岗位设置2.4 第四步&#xff1a;客户成功文化转型2.5 第五步&#xff1a;客户成功人才招…

HEC-RAS 1D/2D水动力与水环境模拟从小白到精通

专题一 水动力模型基础 1.水动力模型的本质 2.水动力模型的基本方程与适用范围 3.模型建模要点 4.注意事项与建模经验 专题二 恒定流模型(1D/2D) 1.恒定流及其适用范围 2.水面线分析及其数据要求 3.曼宁公式与恒定流&#xff0c;后处理 4.HEC-RA的水工建筑物&#xff…

虚拟机桥接模式下没有无线网卡选项

我以为是雷电模拟器占用了网卡的缘故&#xff0c;但想起之前可能修改了无线网卡的某些内容&#xff0c;于是到网络属性里面查看。 如下所示&#xff0c;原来是之前我不小心把这个红箭头指向的项目取消勾选了。

基于微信小程序的车位预定系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言用户的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W…

SpringAOP入门案例

package com.elf.spring.aop.aspectj; /*** author 45* version 1.0*/ public interface UsbInterface {public void work(); }package com.elf.spring.aop.aspectj; import org.springframework.stereotype.Component; /*** author 45* version 1.0*/ Component //把Phone对象…

通过http发送post请求的三种Content-Type分析

通过okhttp向服务端发起post网络请求&#xff0c;可以通过Content-Type设置发送请求数据的格式。 常用到的三种&#xff1a; 1&#xff09;application/x-www-form-urlencoded; charsetutf-8 2&#xff09;application/json; charsetutf-8 3&#xff09;multipart/form-dat…

【论文阅读 09】融合门控自注意力机制的生成对抗网络视频异常检测

2021年 中国图象图形学报 摘 要 背景&#xff1a; 视频异常行为检测是智能监控技术的研究重点&#xff0c;广泛应用于社会安防领域。当前的挑战之一是如何提高异常检测的准确性&#xff0c;这需要有效地建模视频数据的空间维度和时间维度信息。生成对抗网络&#xff08;GANs&…