2. 静态分析基础

各位同学,欢迎来到第二章。上一章我们聊了静态分析能帮我们揪出哪些问题,这一章咱们直接切入正题——MISRA C 2012 的规则到底是怎么组织的。

说实话,我第一次翻开 MISRA 文档的时候,头都大了。几百条规则,密密麻麻的编号,什么 Dir、Rule、App,完全摸不着头脑。后来在项目里一条条啃下来,才发现它的分类和编号体系其实非常清晰。今天我就把这个体系掰开揉碎了讲给你听。

规则的三个层级:强制、必要、建议

MISRA C 2012 把规则分成了三个等级。这个分级直接决定了你在项目里怎么对待它。

分类 英文术语 含义 我的建议
强制 Mandatory 必须遵守,没有例外 零容忍,违反就是违规
必要 Required 必须遵守,但可申请偏差 大部分项目都严格执行
建议 Advisory 推荐遵守,不强制 能遵守尽量遵守

关键点:强制规则是红线,碰了就违规。必要规则是底线,但可以通过正式的偏差申请流程豁免。建议规则嘛……我个人习惯是能改就改,毕竟 MISRA 的建议背后都有血的教训。

我在一个汽车电子项目里遇到过一件事。团队里有个同事觉得某条必要规则「太死板」,直接跳过了。结果代码评审的时候被客户 QA 当场揪出来,差点导致交付延期。嗯,从那以后,没人再敢轻视必要规则了。

规则编号体系:Dir、Rule、App 的区别

MISRA C 2012 的编号看起来有点复杂,其实规律很简单。我总结了一张表,你一看就明白。

前缀 全称 数量 说明
Dir Directive 16 条 指导性原则,通常无法通过静态分析自动检查
Rule Rule 143 条 具体规则,大部分可由工具自动检查
App Appendix 若干 附录,包含示例和补充说明

举个例子:Dir 4.1 说的是「运行时错误应被避免或处理」,这是一条指导性原则,工具很难自动判断你的代码是否「处理」了运行时错误。而 Rule 10.1 规定「表达式中操作数的类型必须符合特定规则」,这个静态分析工具就能直接帮你检查。

小技巧:在配置静态分析工具时,优先开启所有 Rule 类检查。Dir 类规则需要人工走查来补充,别指望工具能搞定一切。

规则编号的命名规则

每条规则都有一个唯一的编号,格式是 分类 章节号.序号。比如 Rule 8.4,8 是章节号,4 是该章节下的第 4 条规则。

章节号对应的是 C 语言的不同方面:

  • 章节 1-7:环境、语言扩展、注释、字符集、标识符、类型、常量
  • 章节 8-9:声明、初始化
  • 章节 10-13:表达式、控制流、指针、类型转换
  • 章节 14-16:循环、跳转、函数
  • 章节 17-22:指针算术、预处理、标准库、资源管理

你想想看,这个编号体系其实很贴心。看到 Rule 10.x,你就知道它在讲表达式相关的规则。看到 Rule 21.x,就知道是标准库的事。

与 C99/C11 的关系

MISRA C 2012 是基于 C99 标准制定的,同时也考虑了 C11 的一些特性。但要注意,它并不是完全覆盖 C99 或 C11 的所有内容。

方面 说明
基础标准 以 C99 为基准,兼容大部分 C11 特性
禁止的特性 明确禁止使用 C99 中的某些特性(如变长数组)
C11 支持 2012 年发布时已考虑 C11,但未完全覆盖
后续更新 MISRA C 2012 Amendment 1 补充了对 C11 的支持

注意:如果你的项目使用了 C11 的某些新特性(比如泛型选择、静态断言),一定要确认 MISRA C 2012 是否允许。我记得有个项目用了 C11 的匿名结构体,结果发现 MISRA 规则里没有明确说明,最后只能走偏差申请流程。

知识体系总览

下面这张图把 MISRA C 2012 的核心规则体系串起来了。你可以把它当作一张地图,后续学习时随时回来对照。

MISRA C 2012 核心规则体系 MISRA C 2012 核心规则体系 强制 (Mandatory) 必要 (Required) 建议 (Advisory) Dir 1-16 指导性原则 Rule 1-143 具体规则 App 附录 示例与补充 章节 1-9 环境 / 声明 / 类型 常量 / 初始化 章节 10-16 表达式 / 控制流 指针 / 循环 / 函数 章节 17-22 指针算术 / 预处理 标准库 / 资源管理 基于 C99,兼容 C11 Amendment 1 补充了对 C11 的完整支持

实际项目中的经验

说了这么多理论,我分享一点实际经验。在配置静态分析工具的时候,我建议你这样做:

  1. 先把所有强制规则打开——没得商量,这是底线。
  2. 必要规则全部打开——但允许团队申请偏差,偏差需要书面记录和评审。
  3. 建议规则选择性打开——我一般会打开 80% 的建议规则,剩下的如果改造成本太高就暂时忽略。

避坑指南:我曾经在一个项目里把所有建议规则都关了,觉得「反正不强制」。结果代码评审时发现,那些建议规则恰恰能防止一些隐蔽的 bug。后来我学乖了——建议规则背后往往藏着前人的血泪史,能开就开。