使代码易于管理的方法之一是加强代码一致性,让任何程序员都可以快速读懂你的代码这点非常重要。保持统一编程风格并遵守约定意味着可以很容易根据“模式匹配”规则来推断各种标识符的含义。创建通用、必需的习惯用语和模式可以使代码更容易理解。虽然在一些情况下可能有充分的理由改变某些编程风格, 但我们还是应该遵循一致性原则,避免代码审查或者任务交接出现不必要的麻烦。
对于编程风格的统一,不仅仅是中小公司面临的棘手问题,对于google这样的大公司,同样存在这样的问题,google的开源项目大多都是用C++开发,正如每个C++程序员都知道的, C++有很多强大的特性,但这种强大不可避免的导致它走向复杂,使代码更容易产生bug,难以阅读和维护。
Google经常会发布一些开源项目,意味着会接受来自其他代码贡献者的代码。但是如果代码贡献者的编程风格与 Google 的不一致,会给代码阅读者和其他代码提交这造成不小的困扰。Google 因此发布了一份自己的编程风格,使所有提交代码的人都能获知 Google 的编程风格。这份规范不仅仅包括了C++风格指南,也包含了C、python、shell和Java。创新工场董事长兼CEO李开复曾经对Google C++编码规范给予了极高的评价:“我认为这是地球上最好的一份C++编程规范,没有之一,建议广大国内外IT研究使用”。
针对C++部分,其主要通过12个章节来约定格式规范,如图1所示,里面针对C++的头文件、类、函数的书写格式做了详细的说明,下面我挑选几个规范做一个介绍。
- Cpplint工具引入
有了上面约定好的一系列编码规范,就可以使我们团队每个成员的代码格式保持一致吗?答案当然是否定的,当然还需要再日常编程过程中去逐渐规范并慢慢培养成习惯,但是如果没有有效的控制行为,依靠人力去检查和维护这些格式,无疑是一个非常繁琐和复杂的工作,为此google开发了自己的C++代码规范检查工具—cpplint。cpplint是一个Python脚本,作为一款开源免费的代码静态检测工具,Google也使用它作为自己的C++代码检测工具,也就是说,只要你想代码遵从Google C++代码规范,那么Cpplint将会提供很好的代码静态检测支持。Cpplint的github仓库可以通过cpplint.git克隆到本地。
cpplint由于是python脚本,所以使用起来很简单,直接在命令行通过“cpplint.py {*.cpp}”即可,针对发现的每一个问题, 都会给出一个位于区间[1, 5]之间的置信度评分, 分数越高就代表问题越肯定。你可以通过verbose选项控制输出哪些级别,如果代码中有些部分不希望被检查,或者你认为cpplint产生了误报,只需要在行尾添加注释 ‘// NOLINT’, cpplint就会跳过这些行. 如果你想过滤掉特定的警告, 就需要设置filter选项了(-表示不输出, +表示输出), 比如写一个测试文件:
- 实际项目中配置Cpplint
虽然可以通过脚本文件对我们的代码进行检查,但是在实际项目中,我们不可能开发完代码之后将代码单独使用cpplint检查一遍,这样不仅繁琐,而且会耗费大量时间去处理。我这里提供三种方案:
- 在jenkins中配置静态检查工具,每次有gitlab merge request 时,自动触发代码静态检查工具,然后进行代码审查,这种方法适用于项目中,所有提交merge request的开发者。每个人提交到gitlab中的代码必须经过cpplint检查才能符合顺利合并的Dev分支。这种方式需要有gitlab权限的开发人员在服务器部署。
- 使用vs code或vs studio集成cpplint插件,每当保存完代码文件后,cpplint则会自动运行插件,以vs code 为例,每当文档发生改变自动保存后,就会用波浪线提示不符合格式规范的代码,同时在终端显示提示信息。只需要在安装cpp-check-lint插件即可。这种方式适合程序员提前预知不符合格式规范的代码,确保在提交前进行自检。
- 在每个开发者的本地,通过git pre-commit 钩子来进行适配。利用钩子检查commit的文件,如果提交的代码不符合cpplint的要求,则不被允许提交,相比于在jenkins中配置静态检查工具,每个人可在本地灵活配置cpplint的配置文件,用来设置不同的过滤等级和测试项,这种方式比较适合每个人在本地测试自己的代码风格,并做一些测试,下面我们主要介绍这种方式。
在每个git托管的项目下,都有一个.git的隐藏目录,里面的hooks文件夹默认配置了很多钩子,只不过默认情况下这些钩子函数是不可用的,如果要启用,需要将.sample取消,然后将以下内容拷贝到pre-commit中,并且在第5行配置正确的cpplint路径。
以上介绍了Google 公司的c++编码规范,他系统的规定了我们书写C++的日常规范,同时配合cpplint这样强大的自动检查工具,为他在日常代码编写规范中提供了切实的落地可能。同时介绍了三种在实际项目中,该工具的配置方法,实际在项目中,三种方法并不是冲突的,可以同时配合使用,提高团队成员开发效率。
当然这个工具也有一定的局限性,由于该规范是以文件为单位进行代码检查,并且目前笔者所在T04项目处于尾期,软件功能已完成90%以上,每次修复一个局部bug,都会检查其他代码的规范,如果严格限制格式,就需要将该文件所有代码重新修改,这样给cpplint的推广也带来了巨大的挑战,但是这对公司后期以C++为语言为主的新项目规范还是有一定帮助的。
一个好的规范是需要大家一起去遵守和维护的,规范逐渐地变成了一种习惯才能提高团队的开发效率,享受规范带来的便捷,就像十字路口的红绿灯,虽然从个体出发,会降低通行效率,但是从十字路口的利用率而言,是提高了每个个体的通行效率和路口的利用效率的。