C++/C
代
码审查
表
文件结构
| ||
重要性
|
审查项
|
结论
|
|
头文件和定义文件的名称是否合理?
|
|
|
头文件和定义文件的目录结构是否合理?
|
|
|
版权和版本声明是否完整?
|
|
重要
|
头
文件是否使用了
ifndef/define/endif
预处
理
块
?
|
|
|
头文件中是否只存放“声明”而不存放“定义”
|
|
|
……
|
|
程序的版式
| ||
重要性
|
审查项
|
结论
|
|
空行是否得体?
|
|
|
代码行内的空格是否得体?
|
|
|
长行拆分是否得体?
|
|
|
“{”
和
“}”
是否各占一行并且对齐于同一列?
|
|
重要
|
一行代
码
是否只做一件事?如只定
义
一个
变
量,只写一条
语
句。
|
|
重要
|
If
、
for
、
while
、
do
等
语
句自占一行,不
论执
行
语
句多少都要加
“{}”
。
|
|
重要
|
在定
义变
量(或参数)
时
,是否将修
饰
符
*
和
&
紧
靠
变
量名?
|
|
|
注释是否清晰并且必要?
|
|
重要
|
注
释
是否有
错误
或者可能
导
致
误
解?
|
|
重要
|
类结
构的
public, protected, private
顺
序是否在所有的程序中保持一致?
|
|
|
……
|
|
命名规则
| ||
重要性
|
审查项
|
结论
|
重要
|
命名
规则
是否与所采用的操作系
统
或
开发
工具的
风
格保持一致?
|
|
|
标识符是否直观且可以拼读?
|
|
|
标识符的长度应当
符合
“min-length && max-information”
原
则
?
|
|
重要
|
程序中是否出
现
相同的局部
变
量和全部
变
量?
|
|
|
类名、函数名、变量和参数、常量的书写格式是否遵循一定的规则?
|
|
|
静态变量、全局变量、类的成员变量是否加前缀?
|
|
|
……
|
|
表达式与基本语句
| ||
重要性
|
审查项
|
结论
|
重要
|
如果代
码
行中的运算符比
较
多,是否已
经
用括号清楚地确定表达式的操作
顺
序?
|
|
|
是否编写太复杂或者多用途的复合表达式?
|
|
重要
|
是否将
复
合表达式与
“
真正的数学表达式
”
混淆?
|
|
重要
|
是否用
隐
含
错误
的方式写
if
语
句
?
例如
(
1
)将
布
尔变
量直接与
TRUE
、
FALSE
或者
1
、
0
进
行比
较
。
(
2
)将
浮点
变
量用
“==”
或
“
!
=”
与任何数字比
较
。
(
3
)将
指
针变
量用
“==”
或
“
!
=”
与
NULL
比
较
。
|
|
|
如果循环体内存在逻辑判断,并且循环次数很大,是否已经将逻辑判断移到循环体的外面?
|
|
重要
|
Case
语
句的
结
尾是否忘了加
break
?
|
|
重要
|
是否忘
记
写
switch
的
default
分支?
|
|
重要
|
使用
goto
语
句
时
是否留下
隐
患
?
例如跳
过
了某些
对
象的构造、
变
量的初始化、重要的
计
算等。
|
|
|
……
|
|
常量
| ||
重要性
|
审查项
|
结论
|
|
是否使用含义直观的常量来表示那些将在程序中多次出现的数字或字符串?
|
|
|
在C++ 程序中,是否用const常量取代宏常量?
|
|
重要
|
如果某一常量与其它常量密切相
关
,是否在定
义
中包含了
这种关
系?
|
|
|
是否误解了类中的
const
数据成员?因为
const
数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。
|
|
|
……
|
|
函数设计
| ||
重要性
|
审查项
|
结论
|
|
参数的书写是否完整?不要贪
图
省事只写参数的
类
型而
省略参数名字。
|
|
|
参数命名、顺序是否合理?
|
|
|
参数的个数是否太多?
|
|
|
是否使用类型和数目不确定的参数?
|
|
|
是否省略了函数返回值的类型?
|
|
|
函数名字与返回值类型在语义上是否冲突?
|
|
重要
|
是否将正常
值
和
错误标
志混在一起返回?正常
值应
当用
输
出参数
获
得,而
错误标
志用
return
语
句返回。
|
|
重要
|
在函数体的
“
入口
处
”
,是否用
assert
对
参数的有效性
进
行
检查
?
|
|
重要
|
使用
滥
用了
assert
?
例如混淆非法情况与
错误
情况,后者是必然存在的并且是一定要作出
处
理的。
|
|
重要
|
return
语
句是否返回指向
“
栈
内存
”
的
“
指
针
”
或者
“
引用
”
?
|
|
|
是否使用
const
提高函数的健壮性?
const
可以
强
制保
护
函数的参数、返回
值
,甚至函数的定
义
体。
“Use const whenever you need”
|
|
|
……
|
|
内存管理
| ||
重要性
|
审查项
|
结论
|
重要
|
用
malloc
或
new
申
请
内存之后,是否立即
检查
指
针值
是否
为
NULL
?(防止使用指
针值为
NULL
的内存)
|
|
重要
|
是否忘
记为
数
组
和
动态
内存
赋
初
值
?(
防止
将未被初始化的内存作
为
右
值
使用)
|
|
重要
|
数
组
或指
针
的下
标
是否越界?
|
|
重要
|
动态
内存的申
请
与
释
放是否配
对
?(防止内存泄漏)
|
|
重要
|
是否有效地
处
理了
“
内存耗尽
”
问题
?
|
|
重要
|
是否修改
“
指向常量的指
针
”
的内容?
|
|
重要
|
是否出
现
野指
针
?例如
(
1
)指
针变
量没有被初始化。
(
2
)用
free
或
delete
释
放了内存之后,忘
记
将指
针设
置
为
NULL
。
|
|
重要
|
是否将
malloc/free
和
new/delete
混淆使用?
|
|
重要
|
malloc
语
句是否正确无
误
?例如
字
节
数是否正确?
类
型
转换
是否
正确?
|
|
重要
|
在
创
建与
释
放
动态对
象数
组时
,
new/delete
的
语
句是否
正确无
误
?
|
|
|
……
|
|
C++
函数的高级特性
| ||
重要性
|
审查项
|
结论
|
|
重载函数是否有二义性?
|
|
重要
|
是否混淆了成
员
函数的重
载
、覆盖与
隐
藏?
|
|
|
运算符的重载是否符合制定的编程规范?
|
|
|
是否滥用内联函数?例如函数体内的代码比较长,函数体内出现循环。
|
|
重要
|
是否用内
联
函数取代了宏代
码
?
|
|
|
……
|
|
类的构造函数、析构函数和赋值函数
| ||
重要性
|
审查项
|
结论
|
重要
|
是否
违
背
编
程
规
范而
让
C++
编译
器自
动为类产
生四个缺省的函数:
(
1
)
缺省的
无参数构造函数;(
2
)缺省的拷
贝
构造函数;(
3
)缺省的析构函数;(
4
)缺省的
赋值
函数。
|
|
重要
|
构造函数中是否
遗
漏了某些初始化工作?
|
|
重要
|
是否正确地使用构造函数的初始化表?
|
|
重要
|
析构函数中是否
遗
漏了某些清除工作?
|
|
|
是否错写、错用了拷贝构造函数和赋值函数?
|
|
重要
|
赋值
函数一般分四个
步骤
:(
1
)
检查
自
赋值
;(
2
)
释
放原有内存
资
源;(
3
)分配新的内存
资
源,并
复
制内容;(
4
)返回
*this
。是否
遗
漏了重要
步骤
?
|
|
重要
|
是否正确地
编
写了派生
类
的构造函数、析构函数、
赋值
函数?注意事
项
:
(
1
)派生
类
不可能
继
承基
类
的构造函数、析构函数、
赋值
函数。
(
2
)派生
类
的构造函数
应
在其初始化表里
调
用基
类
的构造函数。
(
3
)基
类
与派生
类
的析构函数
应该为
虚(即加
virtual
关键
字)。
(
4
)在
编
写派生
类
的
赋值
函数
时
,注意不要忘
记对
基
类
的数据成
员
重新
赋值
。
|
|
|
……
|
|
类的高级特性
| ||
重要性
|
审查项
|
结论
|
重要
|
是否
违
背了
继
承和
组
合的
规则
?
(
1
)若在
逻辑
上
B
是
A
的
“
一
种
”
,并且
A
的所有功能和属性
对
B
而言都有意
义
,
则
允
许
B
继
承
A
的功能和属性。
(
2
)若在
逻辑
上
A
是
B
的
“
一部分
”
(
a part of
),
则
不允
许
B
从
A
派生,而是要用
A
和其它
东
西
组
合出
B
。
|
|
|
……
|
|
其它常见问题
| ||
重要性
|
审查项
|
结论
|
重要
|
数据
类
型
问题
:
(1)
变
量的数据
类
型有
错误吗
?
(2)存在不同数据
类
型的
赋值吗
?
(3)存在不同数据
类
型的比
较吗
?
|
|
重要
|
变
量
值问题
:
(1)
变
量的初始化或缺省
值
有
错误吗
?
(2)
变
量
发
生上溢或下溢
吗
?
(3)
变
量的精度
够吗
?
|
|
重要
|
逻辑
判断
问题
:
(1)由于精度原因
导
致比
较
无效
吗
?
(2)表达式中的
优
先
级
有
误吗
?
(3)
逻辑
判断
结
果
颠
倒
吗
?
|
|
重要
|
循
环问题
:
(1)循
环终
止条件不正确
吗
?
(2)无法正常
终
止(死循
环
)
吗
?
(3)
错误
地修改循
环变
量
吗
?
(4)存在
误
差累
积吗
?
|
|
重要
|
错误处
理
问题
:
(1)忘
记进
行
错误处
理
吗
?
(2)
错误处
理程序
块
一直没有机会被运行?
(3)
错误处
理程序
块
本身就有毛病
吗
?如
报
告的
错误
与
实际错误
不一致,
处
理方式不正确等等。
(4)
错误处
理程序
块
是
“
马
后炮
”
吗
?如在被它被
调
用之前
软
件已
经
出
错
。
|
|
重要
|
文件
I/O
问题
:
(1)
对
不存在的或者
错误
的文件
进
行操作
吗
?
(2)文件以不正确的方式打
开吗
?
(3)文件
结
束判断不正确
吗
?
(4)没有正确地
关闭
文件
吗
?
|
|