第二章 编码规范基础:规则与建议的区别、违反规则的严重性等级、如何阅读MISRA-C规则文档
各位同学好,我是老李。今天咱们聊聊MISRA规范的基础概念。说实话,很多工程师拿到MISRA文档,第一反应就是——好厚一本,从哪看起?
别急,我们先搞清楚几个核心概念。搞懂了这些,你再看文档,思路就清晰多了。
2.1 规则与建议:一字之差,天壤之别
MISRA规范里,把要求分成了两类:规则(Rule)和建议(Advisory)。这两者有什么区别?我直接说结论:规则是强制性的,建议是推荐性的。
| 类别 | 标识 | 含义 | 违反后果 |
|---|---|---|---|
| 规则(Rule) | Rule | 必须遵守,没有例外 | 直接判定为违规,需要修改 |
| 建议(Advisory) | Advisory | 强烈推荐,但允许有理由的偏离 | 建议遵守,偏离需书面说明 |
举个例子。MISRA C:2012 有一条规则:Rule 10.1——操作数不能是基本类型以外的表达式。这是硬性规定,你违反了,静态检查工具直接报错。
而有些建议,比如 Advisory 2.7——避免使用浮点数。嗯,这个就是建议。你非要用浮点数,只要你能说清楚为什么必须用,并且做好防护,也是可以的。
2.2 违反规则的严重性等级:不是所有错误都致命
MISRA把违反规则的严重性分成了三个等级。你想想看,一个指针越界和一个变量命名不规范,能一样处理吗?
| 等级 | 标识 | 典型场景 | 处理方式 |
|---|---|---|---|
| 严重(Mandatory) | M | 未定义行为、内存泄漏、类型转换错误 | 必须修复,否则不能发布 |
| 必要(Required) | R | 控制流问题、表达式副作用 | 必须修复,可申请偏离 |
| 建议(Advisory) | A | 代码风格、注释规范 | 建议修复,偏离需记录 |
我记得有一次,团队里一个小伙子写了个代码:if (x = 5)。这属于严重等级,因为赋值操作符在条件表达式里,极大概率是笔误。静态检查直接标红,编译都过不了。
而像“函数参数个数不超过5个”这种建议,违反了不会出事故,但代码可读性会变差。我一般会要求团队尽量遵守,实在不行就写个注释说明原因。
2.3 如何阅读MISRA-C规则文档
好,现在咱们聊聊怎么读MISRA文档。很多新手拿到文档,从头翻到尾,看完就忘了。我教你一个方法:三步阅读法。
- 第一步:看目录,找分类
MISRA文档按主题分类,比如:
- 环境(Environment)
- 语言扩展(Language Extensions)
- 注释(Comments)
- 字符集(Character Sets)
- 标识符(Identifiers)
- 类型(Types)
- 表达式(Expressions)
- 控制流(Control Flow)
- 等等
你先找到自己关心的章节,比如你正在写表达式相关的代码,就看“表达式”那一章。
- 第二步:看规则编号,判断优先级
每条规则都有编号,比如 Rule 10.1。编号前面的数字代表章节,后面的数字代表序号。你重点关注严重等级为M和R的规则。
- 第三步:看规则正文,理解“为什么”
每条规则都包含:
- 规则描述:一句话说明规则内容
- 原理:为什么要有这条规则
- 示例:合规和不合规的代码对比
- 例外:什么情况下可以违反
我建议你重点看“原理”和“示例”。理解了为什么,你才能记住规则。
举个例子: Rule 12.1 说“表达式的优先级应该用括号明确”。原理是:避免运算符优先级导致的歧义。示例:
// 不合规
if (a & b == c) // 实际被解析为 a & (b == c)
// 合规
if ((a & b) == c) // 明确意图
你看,加个括号,歧义就没了。
2.4 知识体系总览
下面这张图,帮你把本章的知识点串起来。我画了个结构图,你看一眼就明白了。
这张图把本章的核心知识点都串起来了。你以后看MISRA文档,就按这个思路来:先分清楚是规则还是建议,再看严重等级,最后用三步法去读具体内容。