CC++代码检视要点x_第1页
CC++代码检视要点x_第2页
CC++代码检视要点x_第3页
CC++代码检视要点x_第4页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、cc+代码检视要点x c/c+ 代码检视要点 marginwidth=0 marginheight=0 src=l frameborder=0 width=728 scrolling=no height=90 版权申明:以下内容属于正在写作的软件测试实践一书的内容,未经许可不得用于任何正式出版物中,如果转载请注明出处。 :周伟明 4.1.1 c/c+代码检视要点 代码检视要点 代码检视技能属于开发人员的基本功,能够很大程度地反应出开发人员的能力水平,前面 4.4.1 节已经讲过提高评审检视的方法。下面以实际的 c/c+语言方面的代码来讲解代码检视的一些基本关注点和重点检查的内容。 从 c/c+

2、语言开发的代码来讲,检视时主要关注以下一些方面: 与详细设计的一致性 编译设置 头文件 宏定义检查 常量 全局与共享变量 静态变量和函数 数据结构 初始化 字符串 输入校验 内存分配和释放 边界条件 计算 类型转换 指针 数组使用 函数 系统和标准库调用 规范性 冗余代码 判断循环条件 n 解释文字 资源释放 特殊的语法规则 可移植性 n 网络功能 下面对这些需要关注的方面进行更进一步的说明: 1 、 与详细设计的一致性 与详细设计的一致性 只要将检视的代码对照详细设计进行比较就很容易检查出代码是否和详细设计一致,采用逐行逐字进行比较的方法进行。 2 、 编译设置 编译设置 编译设置主要检查以

3、下方面: 使用了优化选项,优化类型和项目所需要的类型是否一致 n 是否正确使用了编译预定义的宏?比如在 vc 中使用 winsock2.0 时要定义win32_lean_and_mean 宏 是多线程还是单线程模式 结构体对齐字节数设置是否正确,跨平台时会不会有问题 n 调用系统的库是静态编译进程序内还是使用动态库调用形式?比如使用 mfc就存在这个问题 n 发行版中连接的库是否误连接了调试版本的库(可能会出现将调试版设置拷贝到发行版,导致发行版本中连接了调试版本的库) n include 路径和 lib 路径设置是否正确,否则装有多个编译器的情况下有可能使用了不正确的头文件和库 3 、 头文

4、件检查 件检查 头文件检查主要关注以下方面: 是否包含有多余的其他头文件 头文件是否内聚,即是否多个模块共用一个头文件 多个头文件的引用是否有先后顺序问题 解释是否规范 头文件内的内容是否清晰,是否分类排放好并给出了足够的解释 包含的系统头文件是否有系统兼容性和移植性的问题 n 是否使用了象 #ifdef _list_h_ 之类的宏定义保证头文件不被重复引用 4 、 宏定义检查 宏定义检查 n 宏定义中有参数和表达式时,参数和表达式是否都用括号括起来了。例如: #define add(a, b) (a + b) /正确的应该是 (a) + (b) 这个定义中就没有将参数 a 和 b 括起来,如

5、果使用时 a 和 b 是表达式的话,就会因为运算符顺序问题而出问题。 续行符/是否使用正确 引号"'是否使用正确 n 代码中编译或调试开关的宏是否正确设置 5 、 常量 常量 常量方面主要检查的主要问题如下: n 常量是否书写正确,两种典型错误,一是数字或字母由于键盘失误写错,比如 2 写成 3 或 1 等。另一种是常量里有位顺序,将位顺序搞错了。 常量是否使用了宏来进行定义 程序中是否存在魔法数字 16 进制数据是否在前面加上了 0x 常量是否来自规格 n 不来自规格的常量的值是否合理 6 、 全局变量与共享变量 全局变量与共享变量 全局变量与共享变量需要检查的主要问题如下

6、: 全局变量是否必须的,是否可以改成局部变量? 是否有多个任务访问共享变量,是否进行了有效的保护 当全局变量只限于本文件内使用时,是否定义成静态的? n 多个任务读写共享变量时,是否可以将读写操作封装成独立函数,而不是在每个模块里都进行加锁解锁操作 7 、 静态变量和函数 静态变量和函数 静态变量和函数检视时主要问题如下: 静态变量的使用是否正确 每次使用静态变量时是否需要重新初始化 对不需要重新初始化的静态变量在多次使用后是否有溢出的问题。 n 文件内部使用的函数是否定义成静态的 8 、 数据结构 数据结构 数据结构方面考虑的主要问题如下: 数据结构里的成员类型定义是否正确 结构体里面变量顺

7、序安排是否合理,数据是否对齐 是否存在冗余未用的成员变量。 类里面是否有私有变量和私有函数放到了公有的定义里去了 n 是否有多个任务调用了数据结构的操作时,是否存在数据重入问题 9 、 初始化 初始化 初始化考虑的主要问题如下: 变量使用前是否需要初始化 n 类的构造函数中是否对需要初始化的成员都进行了初始化(使用成员初始序列进行初始化或在函数体内部进行赋值进行初始化) 初始化的值是否书写正确 数组的初始化是否正确 n 内存或数组在每次使用前是否需要初始化清零 多个初始化赋值时是否存在顺序问题 静态变量和全局变量的初始化是否存在初始化顺序问题 n 字符串数组是否有不需要初始化清零,而只需操作完

8、后在尾部添加/0的情况 10 、 字符串 字符串 检视字符串时考虑的主要问题如下: 以/0结尾 是否会超长 字符串使用的空间大小是否存在差 1 问题 使用字符串指针时,指向的位置是否存在差 1 问题 n 输入的字符串前后有空格 tab 键、回车键等特殊字符时,程序中是否将前后这些特殊字符删除掉。 指针是否可以为空,为空时会有什么现象? 内容为空(即第一个字符为/0)时会发生什么现象? 如果有转义字符"/'字符时,是否正确地写成了"/' 字符串中有斜杠/时,是否误写成反斜杠/ 在对字符串进行拷贝或连接操作时,是否对空间大小进行校验? n 是否有大小写的问题?

9、11 、 输入校验 输入校验 输入校验需要检视的主要问题如下: 函数参数是否需要进行了校验? 从文件读取的数据是否进行了 使用全局数据时 通信收到的数据是否需要进行校验? n 从消息中接受到的数据是否需要进行校验? 12 、 内存分配和释放 内存分配和释放 内存分配方面需要检查的有以下几点: n 分配的大小是否正确,是否分配了过大的内存或者分配的内存大小不足,分配的内存大小是否存在差 1 错误 内存是否经过判断或者进行异常处理 重新分配一块内存时,是否将原有内存释放 分配的内存是否需要初始化清零 n 是否有在大循环中不断分配内存导致可能出现系统内存不足情况 释放方面需要检查的有以下几点: 所有

10、的分支路径上是否将分配的内存进行了释放 是否将已经释放的内存重复释放 n 释放的是否是空指针 是否错误释放了另外一个相似的指针 释放多块内存时是否存在释放的先后顺序问题 n 是否将动态库中分配的内存在动态库外部释放掉或者动态库外部分配的内存却在动态库内释放 使用 realloc()时要考虑以下几点: 新增空间是否需要初始化清零? n 是否还有指针指向老的内存块,并在 realloc()后使用指向老的内存块的指针。 13 、 边界条件 边界条件 凡是牵涉边界条件的地方都需要进行边界检查,以下的一些问题供参考: 循环变量上的边界是否正确 变量的取值是否有边界条件限制,边界是否给出并书写正确? 空间

11、边界,如内存大小,数组大小是否正确,是否存在差 1 和越界情况? 数据结构边界,如链表的头一条记录和最后一条记录等边界情况 服务器连接数量最大是多少 n 断掉网线或打印机缺纸时会发生什么? 关于边界的具体情况,请参阅本书第 3 章的 3.6.2 节,里面有对整数和字符串边界的详细材料。 14 、 计算 计算 计算错误也是程序中经常遇到的一个问题,大部分计算错误可以经过测试发现,但并不是所有的计算错误都可以很容易通过测试来发现,以下的一些问题供检视时参考: 计算表达式或公式是否书写正确,需要逐字符地进行确认没有输入错误 n 表达式中运算符顺序是否书写正确,同优先级运算符运算时是否存在自左至右结合

12、或自右至左结合运算结果不同的问题 是否需要使用括号来保证运算顺序的性和增加程序的可读性 表达式中括号过多时,括号书写是否正确 是否存在计算溢出情况,如两个整数相乘结果超出整数最大范围等情况 n 截断误差和舍入误差是否会引起问题,误差是否会累积下去导致误差越来越大? n 是否存在除零问题(即零做分母的问题),或者两个整数相除结果得到零然后再和其他整数相乘。 n 加减号是否写错,这两个符号在键盘相邻位置,很容易造成键盘输入失误导致写错 可以对算法进行优化提高效率 是否存在某个变量会累积增加导致长时间运行后的溢出 n 计算结果是否存在差 1 错误 15 、 类型转换 类型转换 类型转换的检查有以下问

13、题供参考: 类型转换是否采用安全的转换机制 当采用强制转换时是否会出问题 signed 和 unsigned 转换是否存在问题 转换前是否进行安全校验 是否将小空间的类型转换成了大空间的类型 n 类型转换是否会造成截断、溢出或越界 16 、 指针使用 指针使用 指针在 c/c+中是使用最广泛的一种语法,这也是 c/c+有别于 java,fortran,basic 等语言的地方,指针使得语言的功能强大起来,但也给程序质量带来了很大麻烦,使用指针时是极易出错的,可以说 c/c+代码中的缺陷大部分都与指针有关,下面给出检视指针的一些问题参考: 是否初始化 指针类型定义是否正确 使用前是否申请了内存

14、引用是否正确,是否引用了释放掉的空间 指向的空间是否正确 是否存在野指针现象 释放后再使用时是否需要重新初始化 是否使用了空指针,函数指针是否为空就被调用 是否需要校验 进行类型转换时是否会引起问题 n 指针地址运算是否有误,在地址相加时是否考虑了相加的数字要乘以指针类型大小。比如 int *p; p+1 相比 p 的大小不是大于 1,而是大于一个整数所占空间的字节数。 17 、 数组使用 数组使用 数组的使用也是很容易出错的一种,不幸的是现在还没有足够好的方法能保证数组越界一类的问题得到完美的解决,所以通过对数组的检视来保证质量就很重要了,下面给出检视数组的一些建议: 类型是否正确 多维数组

15、是否数据存放顺序正确 数组使用时是否会越界,空间大小是否存在差 1 错误 作用域是否正确 n 数组大小是否太大导致浪费 18 、 函数 函数 函数方面的一些检视建议如下: 函数调用的参数传递是否正确, 是否有形参和实参使用错误的问题, n 调用函数前是否需要校验, 函数的返回值和输出是否需要校验, 调用的函数是否对全局数据产生影响 功能单一,是否在函数里处理了多个不同的功能 函数参数是否需要定义为 const 回调函数原型是否和定义一致 n 函数是否过长(一般以不超过 200 行为宜) 19 、 系统和标准库调用 系统和标准库调用 调用系统函数和库函数时,以下一些检视建议供参考: 系统调用是否

16、正确,调用参数设置是否正确? 是否按照标准文档中的要求和注意事项进行了调用 于存在 bug 的系统函数是否采取了规避措施进行调用 对调用系统函数是否需要在调用前进行了输入校验? n 调用后是否需要对输出进行校验? 20 、 规范性 规范性 规范性方面的一些检视建议如下: 符合内部的编码规范 是否和业界的编码规范兼容 解释格式规范是否符合要求 代码修改时的解释是否记录了时间和修改者信息以便于跟踪 变量命名是否易于理解 多个变量名是否容易造成混淆?是否有多个命名相似的变量在一起? n 是否有全局范围内变量和局部范围内变量重名情况 21 、 冗余代码 冗余代码 冗余代码在程序中虽然不直接影响质量,但

17、会影响程序的可读性,给后续维护增加困难,因此程序中的冗余的代码最好都删除掉,检查冗余代码时,以下建议供参考: 代码中是否存在无用的调试和测试代码 废弃不用的函数代码 n 是否存在解释掉的一些垃圾代码,不仅要检查使用解释符号/*/ 和/解释掉的代码,还要检查使用宏定义解释掉的代码,如#if 0 解释掉或 #ifdefined (_macro_) 之类的宏定义的解释掉的代码 22 、 判断循环条件 判断循环条件 在程序中的判断和循环条件中,也存在着一些有时通过测试难以发现的问题,主要的检视建议如下: n 是否将,两个符号写错,这两个符号在键盘相邻位置,很容易造成键盘输入失误 逻辑运算符正确,如|

18、和|,和运算符是否搞混淆掉或键盘失误写错, n 逻辑等号=是否误写成等号= n 运算符顺序是否正确,运算符| 、,|、,=、= 的运算顺序需要特别注意 n 循环判断中的表达式是否正确地使用了括号将运算顺序区分开,并增加可读性 表达式运算是否存在逻辑上的错误 对浮点数误用了精确相等进行比较 变量是否进行了初始化 中止条件是否在某些情况下无法到达而造成死循环 循环的边界上是否会造成问题 n 判断条件是否会恒真或恒假 23 、 解释文字 解释文字 解释和文字方面的一些检视建议如下: n 代码中的解释是否达到一定比例,一般要求 2030左右的解释,即解释行占整个代码行的比例要达到 2030左右。当然根

19、据不同的项目类型和编码风格,解释率要求会有所不同 n 是否要求按一定的格式进行解释,有些工具可以将代码中的解释导出来形成文档,比如 doc+工具就可以将符合一定解释规范的解释导出来形成文档 n 函数头的解释检查,函数内容描述是否足够帮助理解函数的行为,参数和返回值描述是否足够帮助调用函数的人如何使用函数,参数的范围是否进行了描述 程序处理是否和解释中的描述一致 函数中的关键地方是否都进行解释,特别是一些难于理解的地方是否有解释 修改的地方是否进行了解释说明修改原因和记录修改的时间和修改人 n 程序中的信息文字是否都集中放在一个地方,便于本地化。 24 、 资源释放 资源释放 资源释放方面的一些

20、检视建议如下: 所有的资源是否都进行了释放 释放前要进行合法性检查以避免重复释放或释放掉还未分配的资源 要检查是否存在某条路径遗漏了释放 n 打开文件是否关闭了,信号量是否释放,句柄是否关闭,锁资源是否释放,是否存在死锁问题 全局的资源是否存在随时间累积增加不减少的问题? 其他各种资源如网络 socket 等是否在各条对应路径上进行了关闭 类的析构函数中是否对类中需要释放的成员进行了释放 n 是否存在在一个模块中分配却在另外一个模块释放现象 25 、 特殊的语法规则 特殊的语法规则 c+中有许多的语法规则需要注意,稍有不慎就会造成问题,以下几点建议供参考: 类中是否需要拷贝构造函数 n 函数重

21、载时是否会导致调用到错误的成员函数 是否更多的用包含来替代继承 基类中的析构函数定义成虚函数了吗 静态变量的初始化和使用是否正确 n 重载 new 和 delete 时,是否将原型定义置于所有全局变量和相应头文件之前 n 构造函数中调用虚函数时是否考虑了虚机制不起作用的问题,调用的只是本地版本 使用 setjmp()和 longjmp()时是否考虑了析构函数不被调用的问题 n 异常处理里是否调用了被进行了异常处理的代码 26 、 可移植性 可移植性 以下检查建议供参考: 与相关的调用是否都被封装在专门的模块里 非系统功能封装模块中是否调用了某个系统特有的 api 或函数 是否兼容老的版本 程序中的变量或数据存在大小字节顺序问题 结构体数据对齐格式是否兼容各个系统 n 是否使用了行内汇编代码 27 、 网络功能 网络功能 以下检查建议供参考 连接的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论