1.介绍

经常进行代码测试和静态代码分析的同学,应该会遇到这样的一个问题,就是一个程序段的最后几行,或者一个源文件末尾会出现错误。本文,结合专业的静态代码分析软件PSV-Studio提供错误类型代码库,分析总结为最后几行错误模式,并对此类问题进行示例展示。

2.最后几行的影响

我们在实际编程过程中,经常需要重复编写相似的代码部件或代码段,长时间进行这样类似工作是极其无聊乏味的,所以,我们必不可免要进行复制--粘贴,我们将这类代码片段或函数称为“复制--粘贴”元素。每个人都可能意识到这样会出现问题:伴随着复制粘贴的大量操作,可能会忽略修改一些变化项,从而造成错误。下面,我先给出一个简短的代码示例:

  1. inline Vector3int43& operator+=(const Vector3int32& other)
  2. {
  3. x += other.x;
  4. y += other.y;
  5. z += other.y;
  6. return *this;
  7. }

显而易见,行“z += other.y”出现错误,这里程序员忘记将‘y’换成‘z’。

你可能认为这仅仅是示例代码,不具有代表性,那么本文从PSV-Studio提供错误类型代码库中,挑选一系列具有代表性的错误代码进行展示。

3.重要软件应用或框架源码示例

Source Engine SDK

  1. inline void Init( float ix=0, float iy=0,
  2. float iz=0, float iw = 0 )
  3. {
  4. SetX( ix );
  5. SetY( iy );
  6. SetZ( iz );
  7. SetZ( iw );
  8. }

上面代码中,最后一行应该调用SetW()

Chromium

  1. if (access & FILE_WRITE_ATTRIBUTES)
  2. output.append(ASCIIToUTF16("\tFILE_WRITE_ATTRIBUTES\n"));
  3. if (access & FILE_WRITE_DATA)
  4. output.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n"));
  5. if (access & FILE_WRITE_EA)
  6. output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n"));
  7. if (access & FILE_WRITE_EA)
  8. output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n"));
  9. break;

最后的三个条件判断重复。

ReactOS

  1. if (*ScanString == L'\"' ||
  2. *ScanString == L'^' ||
  3. *ScanString == L'\"')

错误显而易见。

Multi Theft Auto

  1. class CWaterPolySAInterface
  2. {
  3. public:
  4. WORD m_wVertexIDs[3];
  5. };
  6. CWaterPoly* CWaterManagerSA::CreateQuad (....)
  7. {
  8. ....
  9. pInterface->m_wVertexIDs [ 0 ] = pV1->GetID ();
  10. pInterface->m_wVertexIDs [ 1 ] = pV2->GetID ();
  11. pInterface->m_wVertexIDs [ 2 ] = pV3->GetID ();
  12. pInterface->m_wVertexIDs [ 3 ] = pV4->GetID ();
  13. ....
  14. }

最后一行代码是冗余的,因为数组只有3个元素。

Source Engine SDK

  1. intens.x=OrSIMD(AndSIMD(BackgroundColor.x,no_hit_mask),
  2. AndNotSIMD(no_hit_mask,intens.x));
  3. intens.y=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
  4. AndNotSIMD(no_hit_mask,intens.y));
  5. intens.z=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
  6. AndNotSIMD(no_hit_mask,intens.z));

在最后,忘记将BackgroundColor.y替换为 BackGroundColor.z

Trans-Proteomic Pipeline

  1. void setPepMaxProb(....)
  2. {
  3. ....
  4. double max4 = 0.0;
  5. double max5 = 0.0;
  6. double max6 = 0.0;
  7. double max7 = 0.0;
  8. ....
  9. if ( pep3 ) { ... if ( use_joint_probs && prob > max3 ) ... }
  10. ....
  11. if ( pep4 ) { ... if ( use_joint_probs && prob > max4 ) ... }
  12. ....
  13. if ( pep5 ) { ... if ( use_joint_probs && prob > max5 ) ... }
  14. ....
  15. if ( pep6 ) { ... if ( use_joint_probs && prob > max6 ) ... }
  16. ....
  17. if ( pep7 ) { ... if ( use_joint_probs && prob > max6 ) ... }
  18. ....
  19. }

程序员忘记将 prob->max6替换为 prob->max7

SeqAn

  1. inline typename Value<Pipe>::Type const & operator*() {
  2. tmp.i1 = *in.in1;
  3. tmp.i2 = *in.in2;
  4. tmp.i3 = *in.in2;
  5. return tmp;
  6. }

Qt

  1. if (repetition == QStringLiteral("repeat") ||
  2. repetition.isEmpty()) {
  3. pattern->patternRepeatX = true;
  4. pattern->patternRepeatY = true;
  5. } else if (repetition == QStringLiteral("repeat-x")) {
  6. pattern->patternRepeatX = true;
  7. } else if (repetition == QStringLiteral("repeat-y")) {
  8. pattern->patternRepeatY = true;
  9. } else if (repetition == QStringLiteral("no-repeat")) {
  10. pattern->patternRepeatY = false;
  11. pattern->patternRepeatY = false;
  12. } else {
  13. //TODO: exception: SYNTAX_ERR
  14. }

patternRepeatX在最后部分丢失了,正确的代码应该是:

  1. pattern->patternRepeatX = false;
  2. pattern->patternRepeatY = false;

4.总结

从本文中,大家可以知道“复制--粘贴”会带来很多隐患,这是从我们人性角度来看,个人在快要完成工作的时候,极易产生放松的心态,这样反而导致错误的产生。并且,从本文示例中可知,即使是开发Qt框架和Chromium浏览器内核的高级程序员也会发生这样的问题,希望大家形成自己的错误问题示例库,进而帮助自己降低在开发中发生错误的可能。

004_C++常见错误类型总结(一)之最后几行错误的更多相关文章

  1. Android自动化压力测试之Monkey Test Android常见的错误类型及黑白名单的使用方法(四)

    Android常见的错误类型有两种 1.ANR类型 1)在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸) 2)BroadcastReceiver在10秒内没有执行完毕 2.Crash类型 1)异 ...

  2. MySQL常见错误类型

    MySQL常见错误类型:1005:创建表失败1006:创建数据库失败1007:数据库已存在,创建数据库失败1008:数据库不存在,删除数据库失败1009:不能删除数据库文件导致删除数据库失败1010: ...

  3. 【Jmeter自学】常见错误类型(九)

    ==================================================================================================== ...

  4. Monkey压力测试Android常见的错误类型及黑白名单的使用方法

    Android常见的错误类型有两种 1.ANR类型 1)在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸) 2)BroadcastReceiver在10秒内没有执行完毕 2.Crash类型 1)异 ...

  5. PHP基础教程 常见PHP错误类型及屏蔽方法

    程序只要在运行,就免不了会出现错误,错误很常见,比如Error,Notice,Warning等等.这篇文章兄弟连PHP培训 小编来跟大家具体说一下PHP的错误类型和屏蔽方法.在 PHP 中,主要有以下 ...

  6. 【repost】js 常见错误类型

    1)SyntaxError SyntaxError是解析代码时发生的语法错误 // 变量名错误  var 1a;  // 缺少括号  console.log 'hello'); (2)Referenc ...

  7. Python语言常见异常错误类型

    在运行或编写一个程序时常会遇到错误异常,这时python会给你一个错误提示类名,告诉出现了什么样的问题(Python是面向对象语言,所以程序抛出的异常也是类).能很好的理解这些错误提示类名所代表的意思 ...

  8. js常见错误类型

    (1)SyntaxError SyntaxError是解析代码时发生的语法错误 // 变量名错误 var 1a; // 缺少括号 console.log 'hello'); (2)ReferenceE ...

  9. javascript中常见错误类型

    js中控制台报错主分两大类: 第一类:语法错误,这一类错误在javascript预解析的过程中如果遇到,则会导致整个js文件都无法执行. 另一类:统称为异常,这一类的错误会导致在错误出现的那一行之后的 ...

随机推荐

  1. [leetcode]168. Excel Sheet Column Title表格列名编码(十进制和多进制相互转换)

    其实就是一道,十进制转多进制的题 十进制转多进制就是从后边一位一位地取数. 这种题的做法是,每次用n%进制,相当于留下了最后一位,然后把这位添加到结果最前边.结果需要转为进制的符号. 下一次循环的n变 ...

  2. [leetcode]449. Serialize and Deserialize BST设计BST的编解码

    这道题学到了东西. /* 一开始想着中序遍历,但是解码的时候才发现,中序遍历并不能唯一得确定二叉树. 后来看了网上的答案,发现先序遍历是可以的,观察了一下,对于BST,先序遍历确实是可以 唯一得确定. ...

  3. 【目标检测】基于传统算法的目标检测方法总结概述 Viola-Jones | HOG+SVM | DPM | NMS

    "目标检测"是当前计算机视觉和机器学习领域的研究热点.从Viola-Jones Detector.DPM等冷兵器时代的智慧到当今RCNN.YOLO等深度学习土壤孕育下的GPU暴力美 ...

  4. hive集群模式安装

    hadoop3.2.0 完全分布式安装 hive-3.1.1 #解压缩tar -zxvf /usr/local/soft/apache-hive-3.1.1-bin.tar.gz -C /usr/lo ...

  5. TurtleBot3使用课程-第三节b(北京智能佳)

    目录 1.使用TurtleBot3机械手运行SLAM 2 1.1 roscore运行 2 1.2 准备行动 3 1.3 运行SLAM节点 3 1.4 运行turtlebot3_teleop_key节点 ...

  6. TR2021_0000偶发数据库连接异常问题排查

    [问题描述] 数据库连接异常是很难排查的一类问题.因为它牵涉到应用端,网络层和服务器端.任何一个组件异常,都会导致数据库连接失败.开发遇到数据库连接不上的问题,都会第一时间找DBA来协助查看,DBA除 ...

  7. Eplan P8 2.7 加密狗 感叹号 解决方法

    Eplan安装完加密狗后一直感叹号异常,最近也是查了很多办法,最后发现是少了个驱动的原因. 就是上面这个驱动,这里放上驱动链接:https://lanzous.com/id5gi8f ,或者随便找一个 ...

  8. version can neither be null, empty nor blank

    在用mybatis-generator逆向生成mapper和DAO的时候,出现了这个错误. mybatis-generator:generate 原因是在pom.xml中我的mysql依赖没有写版本号 ...

  9. 二 prometheus 监控 Redis

    Prometheus 监控Redis需要用到redis_exporter客户端, Prometheus -> redis_exporter这个模式, 类似监控Mysql 一个思路. 1 ) 设置 ...

  10. 安装MySQL数据库(在Windows下通过zip压缩包安装)

    安装MySQL 这里建议大家使用压缩版,安装快,方便.不复杂. 软件下载 mysql5.7 64位下载地址: https://dev.mysql.com/get/Downloads/MySQL-5.7 ...