代码评审是软件开发中比较重要的环节,主要的目的就是:保证代码质量,保障代码的规范性和可读性;排查错误,避免一些恶性事故的发生。
目前我们的代码评审分两块:
自动化的静态工具Tscancode
当我们有新的文件提交后Tscancode会自动扫描,并检查一些常见的静态错误,比如指针判空,逻辑异常,死代码块等。当然静态工具只是参考,但是也能避免一些简单错误的产生。
人工评审
人工评审最重要的就是排查错误,然后就是代码效率、规范性和可读性。
- 排查错误
C++中最主要的问题基本上都是出在指针上面,其实就是悬空指针、野指针、空指针、越界指针等。
1.悬空指针,指针没有初始化,这种情况一般出现在初始化没有置空且存在分支的赋值逻辑的
int* p;
if(condition)
{
p = new int(5)
}
2.野指针,野指针就是资源删除了,但是指针变量没有设置为nullptr,或者其他指向该对象的指针没有置空并使用。
int * pa = new int(5);
//这里 pb = pa只是显式的写来说明问题,正常人不会这样写,但是lamda表达式值传递,函数入参出参都会产生类似的效果
int * pb = pa;
delete(pa);
pa = nullptr;
//这个时候pb已经是野指针了,这种情况是比较常见且隐蔽的,避免野指针的较好方法就是智能指针了
3.空指针,判空即可
4.越界指针,越界指针这个事情非常容易出现,而且非常难以定位,因为如果式读越界的话,且没有读到为分配的内存区域并不会宕机,而是按对应的格式解释内存中的内容。如果是写的话,可能将其他变量、对象的内存空间写坏 导致未知的事情发生。
vector<int> a;
//loadConfig函数是传入a的引用,配置里面有10个数
LoadConfig(a);
//假设访问的时候没有判断a.size()
cout<<a[100];
// 越界了,读越界内存不一定宕机,但是某一次突然访问到了未分配的内存区域,宕机。
除了指针的问题还有其他的问题:
5.递归函数无限递归,栈溢出
6.除数为0
7.内存泄漏,堆空间用完后没有释放。
- 代码效率
代码效率要对底层的接口比较了解,对业务场景算法和数据结构比较熟悉 经验项。 - 规范性
规范性主要在变量的命名,函数的构建等(这里涉及到一些软件工程理论相关的知识了,高内聚低耦合、开闭原则等等)