随着技术的不断进步,客户期望越来越高,嵌入式设备变得越来越智能,对应的嵌入式系统和软件也变得越来越复杂,同时产品的开发周期变得越来越短。如何在短时间内开发出高质量的软件对产品的成功起着决定性的作用。提高代码质量是一个系统工程,本文主要介绍开发人员如何在日常开发过程中提高代码质量。
什么是代码质量?
代码质量一般用于衡量代码的“好”和“烂”:“好”代码表示代码质量高,“烂”代码表示代码质量低。虽然目前代码质量没有一个单一客观的定义,但是代码质量一般可以通过一些指标来衡量:
- 可读性(Readability):“好”代码应该易于阅读和理解。
- 可靠性(Reliability):“好”代码应该是可靠的(Bug越少,代码质量越高)。
- 可测试性(Testability):“好”代码应该易于测试。
- 可重用性(Reusability):“好”代码应该易于在不同项目里面重用。
- 可维护性(Maintainability):“好”代码应该易于修改和维护。
- 可扩展性(Extensibility):“好”代码应该易于扩展。
- 可移植性(Portability):“好”代码应该易于在不同的平台上移植。
如何提高代码质量?
提高代码质量不是一项一次性任务,而是一项需要长期坚持的实践。下面是目前常用的一些提高代码质量的实践:
- 遵循编码标准:编码标准是前辈总结的一些编码最佳实践和经验教训。编码标准一般分为公司内部编码标准(比如代码风格和命名规则等)和行业编码标准(比如MISRA, CERT和CWE等)。
- 静态代码分析:静态代码分析可以帮助检查代码是否遵循相关编码标准。
- 单元测试:单元测试主要是功能测试,可以帮助测试代码是否符合对应的设计,确保代码功能的正确性。
- 代码审查:代码审查可以加强开发者之间的协作,帮助检查代码中潜在的逻辑问题。
- 使用版本控制:使用版本控制可以管理代码变更历史,同时方便团队协作。
- CI/CD:CI/CD可以实现自动化构建、静态代码分析和单元测试。
为什么需要在日常开发过程中提高代码质量?
下面是Capers Jones 的著作“Applied Software Measurement: Global Analysis of Productivity and Quality”里面关于Bug引入、检测和修复成本的一张图:
- 绝大部分Bug是在日常开发编码阶段引入的。
- Bug发现的越早,越容易修复,修复成本越低;反之Bug发现的越晚,越难修复,修复成本越高。
在日常开发编码阶段过程中提高代码质量,可以尽早发现代码中的Bug,尽快修复代码中的Bug,大大降低修复Bug的成本。
如何在日常开发过程中提高代码质量?
前面介绍了提高代码质量的一些通用实践,下面具体介绍开发人员如何在日常开发过程中提高代码质量。
构建0 Error和0 Warning
在构建的时候,开发人员会做到0 Error (因为Error会导致构建失败)。但是很多时候没有做到0 Warning (因为Warning不会导致构建失败)。但是Waring有可能是潜在的隐藏的Bug。
下面是一个经典的编译器Warning:提示应该使用比较运算符==而不是赋值符=:
修改之后重新构建:0 Error和0 Warning:
静态代码分析
构建0 Error和0 Warning之后,建议先做静态代码分析,因为静态代码分析不需要运行代码,分析起来比较方便快捷,而且静态代码分析能检测出一些常见的代码错误。
在IAR Embedded Workbench当中,只需要先勾选对应的C-STAT静态代码检查规则:
就可以使用C-STAT对整个工程进行静态代码分析:
也可以使用C-STAT对单个文件进行静态代码分析:
分析完成后,对应C-STAT Messages窗口会显示对应检查结果,双击对应信息可以定位到源代码位置:
如果不太熟悉对应检查规则,可以按F1,会弹出对应帮助文档(包含对应检查规则的描述,对应编码标准以及违反和遵循对应规则的代码示例等)来帮助快速定位和解决问题:
根据帮助文档中的信息,推测需要将代码里面的4u改成(int32_t) 4。修改代码之后重新进行静态代码分析,之前的违反修复了:
使用IAR C-STAT可以非常方便地进行静态代码分析并且迅速得到反馈,以确保代码符合相应的编码标准。
单元测试
在静态代码分析之后,建议做单元测试。因为静态代码分析只能检查代码是否遵循相关编码标准,代码的功能测试还需要单元测试。IAR本身没有提供单元测试工具,IAR有很多提供单元测试工具的合作伙伴。同时IAR里面的C-RUN动态代码分析可以帮助在单元测试时发现一些潜在的问题。
在IAR Embedded Workbench当中,只需要勾选对应的C-RUN动态代码检查规则:
重新构建,编译器会在有可能出现违反的地方自动插入对应的测试代码。
在运行的时候C-RUN会检测是否有对应的违反,比如下面C-RUN Messages提示访问越界:
分析发现对应数组的大小是4,但是错误地引用了[4]( [4]是数组的第5个元素),导致访问越界。修改代码之后重新测试OK (C-RUN Messages窗口没有对应违反):
代码审查
在单元测试完成之后,建议邀请同伴做代码审查(为了提高代码审查的效率,建议在构建、静态代码分析和单元测试完成之后再做代码审查)。
CI/CD
在代码审查完成之后,建议上传代码到服务器进行自动化工作流。
IAR提供了对应的自动化工具IAR Build Tools可以通过命令行的方式进行自动化构建、静态代码分析和下载调试(用于单元测试):
总结
在与用户的交流中,我们欣喜地发现越来越多的公司和开发人员意识到代码质量的重要性,但同时也发现了一些问题:
- 有些公司居然没有对代码进行静态代码分析、单元测试和代码审查,代码的正确性和质量完全依靠最后的产品测试。
- 有些公司购买了非常好的静态代码分析和单元测试工具,但是遗憾的是这些工具并没有被开发人员在日常开发过程中充分使用,而是等到发布软件版本之后才对整个工程进行静态代码分析和单元测试。
- 有些公司还没有部署自动化工作流(开发人员的时间非常宝贵,要尽量对代码进行自动化构建、静态代码分析和单元测试,这样开发人员就可以尽快收到反馈,提高代码质量的同时也提升研发效率)。
本文以IAR Embedded Workbench和IAR Build Tools(包含C-STAT静态代码分析和C-RUN动态代码分析)为例介绍了开发人员如何在日常开发过程中提高代码质量。需要注意的是,文中的IAR Embedded Workbench和IAR Build Tools(包含C-STAT静态代码分析和C-RUN动态代码分析)只是工具示例,文中的策略也适用于其它工具。选择对应的工具很重要,但是更重要的是:开发人员需要在日常开发过程中充分利用好对应的工具来提高代码质量。因为绝大部分Bug是在日常开发编码阶段引入的,Bug发现的越早,越容易修复,修复成本越低;反之Bug发现的越晚,越难修复,修复成本越高。
更多信息
更多关于IAR Embedded Workbench和Build Tools(包含C-STAT静态代码分析和C-RUN动态代码分析)的信息,可以参考以下网址: