代码静态检查

使用cppcheck给工程代码做静态检查,主要发现了以下几个问题:

1. 使用C风格的类型转换

警告如下:

C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts.

应该使用C++提供的static_cast, const_cast, dynamic_cast 和 reinterpret_cast 做类型转换,明确转换的类型。

2. 迭代器使用后置叠加(叠减)运算符

警告如下:

Prefix ++/-- operators should be preferred for non-primitive types. Pre-increment/decrement can be more efficient than post-increment/decrement. Post-increment/decrement usually involves keeping a copy of the previous value around and adds a little extra code.

迭代器前置++和后置++ 的运行效率是不同的,前置++效率更高,因为后置运算符需要做一个临时的类对象拷贝。

3. 直接在函数参数中使用C风格字符串。

警告如下:

The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly passing the string.

比如一个函数的参数类型是strng,调用时实参直接使用了C风格的字符串,于是就会有以上提示,主要还是因为这里会造成一个不必要的字符串拷贝,降低运行效率。

4. 使用无用的find

很多时候,我们会写下面的find代码,值不等于-1则说明找到了该字符串,

if(std::string::npos != dataStr.find("what"))//do something

该代码段会导致报警:

Either inefficient or wrong usage of string::find(). string::compare() will be faster if string::find's result is compared with 0, because it will not scan the whole string. If your intention is to check that there are no findings in the string, you should compare with std::string::npos.

代码本身不会出错,但是效率上是不被认可的,如cppcheck所说,如果你希望检查某个字符串是不是某个期望的字符串,那你应该使用compare函数,因为这样更快。

5. 函数参数使用传值而不是传引用

警告如下:

Parameter 'strShowTime' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.

C++给了引用传参,而你不使用,那就是你的问题了。

6. 构造函数没有使用初始化成员变量列表,而是习惯于写入构造函数体

警告有:

Member variable 'CActiveComboItemXml::m_phorActivecombo' is not initialized in the constructor.

或者如:

When an object of a class is created, the constructors of all member variables are called consecutively in the order the variables are declared, even if you don't explicitly write them to the initialization list. You could avoid assigning 'm_strHrefOnPanReady' a value by passing the value to the constructor in the initialization list.

这个问题很普遍,因为很多程序员不习惯在构造函数的初始化列表中初始化成员变量,有的是直接忽略掉,有的则是在构造函数的函数体中去使用赋值运算符赋值,可是这个时候已经不是初始化了,而是赋值阶段了。这是个很危险的习惯!

7.使用memset清空含有string(wstring)类型成员的结构体

警告为:
Using 'memset' on struct that contains a 'std::wstring'. [memsetClass]

在C语言中,使用memset清空内存是常用操作,在C++中,和malloc一样,使用memset直接操作内存是有很大风险的,因为它们都只是在内存层面做了改动,但是对类对象本身却没有任何行动,也就是说,他们不会调用类对象的构造或者析构函数,如果我们的结构体中含有string类型的成员,直接使用memset很可能导致内存泄漏!

这里涉及到一个POD参考的概念。如果一个类不是POD的,那么就不应该使用如mem*,malloc等内存操作函数,否则,我们将得不到我们想要的东西,甚至引发错误。

举一个很简单的例子:

struct struTest
{
string str1;
};void TestStructString()
{struTest tt;    size_t sizestru = sizeof(tt);tt.str1 = "this OK";struTest* tt2 = new struTest;memcpy(tt2,&tt,sizestru);cout << "tt2 str1 is:"<<tt2->str1 <<"\n";delete tt2;//程序奔溃!!!
}

测试程序以memcpy函数为例,运行本程序,虽然tt2可以正常的将str1拷贝进来,但是最后程序奔溃了!!
想想原因是为何? 程序崩溃在tt的析构函数中,因为无法探究memcpy到底做了哪些具体操作,所以我们可以猜测它是将tt的内存区域完整的拷贝到了tt2内,但是,tt2中的strin类型的成员str1并没有完成自己的构造,而是通过内存拷贝的方式完整的使用了tt的数据,那么执行完delete ,tt2的str1也会析构自身,这时其析构的其实是tt的str1。等到tt再去析构自己时,奔溃就发生了!以上只是自己的猜测。可能不是事实,但是,当我把delete tt2注释后,崩溃就消失了,这也能证明自己上面的论述。

问题怎么处理?

在C++中,除非是明确的POD类型,否则放弃使用mem*系包括malloc等传统C内存操作函数。

首先,我们需要弄明白,我们为什么需要使用memet,因为我们需要将这个结构体的数据清零,所以我们真正需要的是一个结构体(类)的构造函数!在类中写一个结构体,将类里的所有成员变量进行列表初始化就可以解决这个问题了。
话说回来,就好像,我们在写C代码时, 如果结构体某个成员类型需要是结构体类型,我们使用了该结构体指针一样,我们同样可以使用string类型的指针来表示该成员类型。毕竟在VS2010环境下,一个string类型的内存占用就是32byte,而一个string*只有4byte。如果担心hold不住指针类型,可以使用智能指针来折中,如shared_ptr,内存的占用将减小到8。事实上,使用智能使用已经是一个最优方案了。

这几个问题大量出现在cppcheck的问题列表中,是我们经常犯的编程问题,应从代码风格上进行规避。
当然了,可能的错误(警告)是由不当的编码风格和不扎实的C++编码基础导致的,通过静态检查我们自己的代码,可以最大层度的写出易读且不容易出错的代码。

推荐大家使用cppcheck!

转载于:https://www.cnblogs.com/Stultz-Lee/p/10061365.html

你需要的代码静态检查相关推荐

  1. linux sparse 内核代码静态检查

    Sparse简介 Sparse诞生于2004年,是由Linux之父开发的,目的就是提供一个静态检查代码的工具,从而减少Linux内核的隐患.起始,在Sparse之前已经有了一个不错的代码静态检查工具( ...

  2. Jenkins 在 Tomcat 中的部署及代码静态检查工具集成

    Jenkins 的简单部署 在安装了 Jenkins 运行所需的依赖(主要是 JDK)之后,可以通过如下步骤简单快速地部署 Jenkins: 下载 Jenkins. 打开终端并切换至下载目录. 运行命 ...

  3. 代码静态检查工具PC-Lint运用实践

    代码静态检查工具PC-Lint运用实践 如何提交zero bug的产品,如何尽早发现bug,是软件开发工程师和测试工程师都需要思考的问题.我认为高质量的代码是关键,具体实施保障办法有:框架约束,代码评 ...

  4. 一些代码静态检查工具的简介

    1.KLOCWORK: 适用语言:C, C++, JAVA 是否开源:否, 是否需要编译:是 作用:代码静态检查工具.用于高效检测软件缺陷和安全隐患,提供优秀的静态源代码分析解决方案.软件号称是业界领 ...

  5. 基于MISRA-C和VS Code的代码静态检查的开源解决方案

    基于MISRA-C和VS Code的代码静态检查的开源解决方案 简介 工具 配置步骤 简介 MISRA-C是汽车嵌入式软件开发中常用的静态代码检查工具.常用的商用静态代码分析工具,比如QAC.Cove ...

  6. 【Dart】Dart代码静态检查

    介绍 代码检查可以有效的提高代码质量,更进一步的说代码检查不仅仅是为了提高代码质量,已深入到代码程序的逻辑检查.内存使用情况的检查甚至更高层面的检查,很大程度上影响了程序的功能和性能. 代码检查分类 ...

  7. React——Flow代码静态检查

    为什么80%的码农都做不了架构师?>>>    Flow Flow是Facebook开源的静态代码检查工具,他的作用是在运行代码之前对React组件以及Jsx语法进行静态代码的检查以 ...

  8. 代码静态检查工具汇总

    静态代码扫描,借用一段网上的原文解释一下(这里叫静态检查):"静态测试包括代码检查.静态结构分析.代码质量度量等.它可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行.代码 ...

  9. cppcheck linux,cppcheck实现c++代码静态检查

    本文案旨在输出方法: 通过jenkins集成cppcheck实现对c++代码的检查,并输出报告,通过报表可以明确分析出问题 Cppcheck是c/c++代码的静态分析工具.它提供了独特的代码分析来检测 ...

最新文章

  1. Dan Gillmor总结微软付费平息纠纷历史
  2. git delete file remote
  3. Go runtime的调度器
  4. leveldb——leveldb入门篇之Linux下编译配置和使用
  5. 【BZOJ】【1096】【ZJOI2007】仓库建设
  6. python画图中grid等于true_python – 散布在GridPlot中覆盖多个绘图对象
  7. console查看对象结构
  8. C编程语言中整型变量在内存中的存储形式介绍
  9. 容器技术Docker K8s 39 Serverless Kubernetes(ASK)详解-阿里云Serverless容器(ASK)适用场景与核心功能
  10. 谷歌浏览器插件安装 音量提升插件Volume Control
  11. YYtext简单使用
  12. 计算机无法更改开机密码,不能修改win7电脑开机密码是怎么回事
  13. Idea中发布JAR包到中央仓库报错问题处理 unable to find valid certification path to requested target
  14. shader拖尾_u3d拖尾特效组件-------TrailRenderer
  15. AD10--添加泪滴
  16. 对服务器整体性能画像,青云科技发布新一代企业级云服务器e3 绘制云基础设施标准画像...
  17. 软件架构设计之如何编排复杂多任务
  18. 物联网毕设分享 stm32 RFID与指纹识别的门禁系统
  19. html5摄像头 在线演示,基于HTML5实现的超酷摄像头(HTML5 webcam)摄
  20. art template 模板渲染数据

热门文章

  1. jQuery事件总结(二)
  2. idea怎么看jdk版本_怎么看自己的jdk版本
  3. python的scipy简介
  4. 解决办法: Vue cross-env NODE_ENV=production webpack --progress --hide-module
  5. Anconda 安装
  6. Anaconda安装指南
  7. 莫队和带修莫队 学习笔记
  8. Evaluations
  9. Apache POI 设置Excel单元格的宽度和高度
  10. html table拓宽,excel拉长单元格_excel调整单元格大小的方法步骤详解