zoukankan      html  css  js  c++  java
  • 004_C++常见错误类型总结(一)之最后几行错误

    1.介绍

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

    2.最后几行的影响

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

    inline Vector3int43& operator+=(const Vector3int32& other)
    {
    	x += other.x;
    	y += other.y;
    	z += other.y;
    	return *this;
    }
    

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

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

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

    Source Engine SDK

    inline void Init( float ix=0, float iy=0,
                      float iz=0, float iw = 0 ) 
    {
      SetX( ix );
      SetY( iy );
      SetZ( iz );
      SetZ( iw );
    }
    

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

    Chromium

    if (access & FILE_WRITE_ATTRIBUTES)
      output.append(ASCIIToUTF16("	FILE_WRITE_ATTRIBUTES
    "));
    if (access & FILE_WRITE_DATA)
      output.append(ASCIIToUTF16("	FILE_WRITE_DATA
    "));
    if (access & FILE_WRITE_EA)
      output.append(ASCIIToUTF16("	FILE_WRITE_EA
    "));
    if (access & FILE_WRITE_EA)
      output.append(ASCIIToUTF16("	FILE_WRITE_EA
    "));
    break;
    

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

    ReactOS

    if (*ScanString == L'"' ||
        *ScanString == L'^' ||
        *ScanString == L'"')
    

    错误显而易见。

    Multi Theft Auto

    class CWaterPolySAInterface
    {
    public:
        WORD m_wVertexIDs[3];
    };
    CWaterPoly* CWaterManagerSA::CreateQuad (....)
    {
      ....
      pInterface->m_wVertexIDs [ 0 ] = pV1->GetID ();
      pInterface->m_wVertexIDs [ 1 ] = pV2->GetID ();
      pInterface->m_wVertexIDs [ 2 ] = pV3->GetID ();
      pInterface->m_wVertexIDs [ 3 ] = pV4->GetID ();
      ....
    }
    

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

    Source Engine SDK

    intens.x=OrSIMD(AndSIMD(BackgroundColor.x,no_hit_mask),
                    AndNotSIMD(no_hit_mask,intens.x));
    intens.y=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
                    AndNotSIMD(no_hit_mask,intens.y));
    intens.z=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
                    AndNotSIMD(no_hit_mask,intens.z));
    

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

    Trans-Proteomic Pipeline

    void setPepMaxProb(....)
    {  
      ....
      double max4 = 0.0;
      double max5 = 0.0;
      double max6 = 0.0;
      double max7 = 0.0;
      ....
      if ( pep3 ) { ... if ( use_joint_probs && prob > max3 ) ... }
      ....
      if ( pep4 ) { ... if ( use_joint_probs && prob > max4 ) ... }
      ....
      if ( pep5 ) { ... if ( use_joint_probs && prob > max5 ) ... }
      ....
      if ( pep6 ) { ... if ( use_joint_probs && prob > max6 ) ... }
      ....
      if ( pep7 ) { ... if ( use_joint_probs && prob > max6 ) ... }
      ....
    }
    

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

    SeqAn

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

    Qt

    if (repetition == QStringLiteral("repeat") ||
        repetition.isEmpty()) {
      pattern->patternRepeatX = true;
      pattern->patternRepeatY = true;
    } else if (repetition == QStringLiteral("repeat-x")) {
      pattern->patternRepeatX = true;
    } else if (repetition == QStringLiteral("repeat-y")) {
      pattern->patternRepeatY = true;
    } else if (repetition == QStringLiteral("no-repeat")) {
      pattern->patternRepeatY = false;
      pattern->patternRepeatY = false;
    } else {
      //TODO: exception: SYNTAX_ERR
    }
    

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

    pattern->patternRepeatX = false;
    pattern->patternRepeatY = false;
    

    4.总结

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

  • 相关阅读:
    Linux知识(4)----文件系统结构
    ROS知识(4)----初级教程之常见问题汇总
    Linux知识(3)----常用快捷键和命令
    ROS知识(1)----ROS Jade安装
    Linux知识(1)----U盘安装Ubantu14.04系统
    Linux知识(2)----中文输入法安装
    EM(Expectation Maximization)算法
    idea xml 绿背景色 去掉拼写检查
    Java transient
    java代码中获取classpath路径
  • 原文地址:https://www.cnblogs.com/zjz-819823900/p/14344359.html
Copyright © 2011-2022 走看看