规则分类与解读:强制规则、必要规则、建议规则的区别与落地策略
MISRA C:2012 一共定义了 143 条规则。刚接触的人一看这个数字,头就大了。其实不用慌,这些规则被分成了三个等级:强制(Mandatory)、必要(Required)和建议(Advisory)。
这三个等级,说白了就是「必须做」、「最好做」和「推荐做」。但实际落地的时候,很多团队把它们混为一谈。我见过不少项目,把建议规则当强制来卡,结果开发效率直线下降;也见过把强制规则当建议来对待,最后合规审查直接翻车。
这一章,我就带你把这三种规则彻底搞清楚。
1. 强制规则(Mandatory)—— 没得商量
强制规则是 MISRA C 里最严格的等级。违反它,代码就是不合规的。没有任何例外,没有任何变通。
这类规则通常涉及 未定义行为 或 严重的安全隐患。比如:
- 不允许使用
#undef取消已定义的宏(规则 3.3) - 不允许在表达式中有副作用(规则 13.2)
- 不允许使用
goto语句(规则 15.1)
我在一个汽车电子项目里遇到过一件事。团队里有个老工程师,习惯用 goto 做错误处理。他觉得「就一个 goto,没事的」。结果合规检查工具一跑,直接标红。客户审计的时候,这个问题被列为「严重不符合项」。最后花了三天重写那部分逻辑,还耽误了交付节点。
所以我的建议是:强制规则,一条都不要碰。工具能自动检查的,就开起来;不能自动检查的,就写进代码评审清单。
2. 必要规则(Required)—— 原则上必须遵守
必要规则是 MISRA C 里数量最多的等级,占了 100 多条。它不像强制规则那么绝对,但原则上你也得遵守。
区别在哪呢?必要规则允许「偏差申请」。也就是说,如果你有充分的理由,并且能证明这样做不会带来风险,就可以申请偏离这条规则。
举个例子:
- 规则 8.4:所有函数声明必须使用原型(即带参数列表的声明)
- 规则 10.1:不允许对浮点类型进行位运算
- 规则 17.4:不允许使用
printf等标准库 I/O 函数
必要规则的落地策略,我总结了一个三步法:
- 默认遵守 —— 代码里先按规则写,不要一开始就想走偏差
- 偏差申请 —— 如果确实需要偏离,写正式的偏差文档,说明理由、风险分析和缓解措施
- 定期复审 —— 偏差不是一劳永逸的。每次版本迭代,都要重新评估偏差是否仍然合理
3. 建议规则(Advisory)—— 推荐但不强制
建议规则是最宽松的等级。它更像是一种「最佳实践」的推荐。你完全可以不遵守,只要你能给出合理的理由。
但这里有个坑:很多团队觉得建议规则「没用」,直接全部忽略。我个人觉得,这有点浪费。
建议规则通常涉及代码的可读性、可维护性和一致性。比如:
- 规则 4.1:八进制常量不应被使用(容易混淆)
- 规则 8.13:指针参数应使用
const限定(如果函数不修改它) - 规则 21.1:不应使用
setjmp和longjmp
我曾经参与过一个医疗设备项目。团队一开始把建议规则全关了,觉得「反正不强制」。结果代码评审的时候,发现很多函数参数没有加 const,导致调用方不确定参数会不会被修改。后来花了大量时间加 const,还改出了几个 bug。
所以我的建议是:建议规则,能遵守就遵守。它不会增加太多工作量,但能显著提升代码质量。如果实在有冲突,比如为了性能优化,那就记录下来,说明理由即可。
4. 三种规则的对比与落地策略
为了让你看得更清楚,我把三种规则的核心差异整理成了表格:
| 维度 | 强制规则 | 必要规则 | 建议规则 |
|---|---|---|---|
| 违反后果 | 直接不合规 | 原则上不合规,可申请偏差 | 不违规,但推荐遵守 |
| 偏差申请 | 不允许 | 允许,需正式文档 | 不需要 |
| 工具检查 | 必须全开 | 建议 90% 以上 | 选择性开启 |
| 典型场景 | 未定义行为、语法错误 | 编码风格、类型安全 | 可读性、可维护性 |
| 落地策略 | 零容忍,自动检查 | 默认遵守 + 偏差管理 | 推荐遵守,记录例外 |
你想想看,如果三种规则都用同一套标准去卡,那开发团队肯定怨声载道。但如果把建议规则全放掉,代码质量又可能滑坡。所以关键在于「分级管理」。
5. 知识体系总览
下面这张图,把三种规则的关系和落地路径画清楚了。你可以把它当作本章的「思维导图」:
6. 避坑指南
最后,分享几个我在项目中踩过的坑:
- 不要把所有规则都开到最高等级。 我曾经见过一个团队,把建议规则也当强制来卡,结果开发周期延长了 30%,团队怨声载道。分级管理才是正道。
- 偏差申请不是「免责金牌」。 有些团队觉得「反正可以申请偏差」,就随意违反必要规则。结果审计的时候,偏差文档写得漏洞百出,反而被扣分。
- 工具检查要分阶段引入。 不要一开始就把所有规则都开起来。先开强制和必要规则,等团队适应了,再逐步开启建议规则。
📌 一句话总结: 强制规则是底线,必要规则是标准,建议规则是追求。落地的时候,按这个优先级来,既保证合规,又不拖累效率。