3. MISRA C规则分类与结构解析
各位同学,欢迎来到第三章。这一章我们不讲具体代码,而是先把MISRA C的规则体系这张地图摊开。我个人习惯是,学任何标准前,先搞清楚它的骨架。你想想看,如果连规则怎么编号、分几类、哪些是红线都不知道,后面排查问题就像没头苍蝇。
MISRA C的规则体系,说白了就是三件事:编号怎么认、规则怎么分组、优先级怎么定。搞懂这三样,你拿到任何一条规则,扫一眼编号就知道它属于哪类、严不严重。
3.1 规则编号体系:Dir与Rule
MISRA C的规则编号分两大类:指令(Directive)和规则(Rule)。我刚开始接触时也纳闷,为什么搞两套?后来踩了坑才明白——这是为了区分“必须做”和“怎么做”。
| 类型 | 前缀 | 含义 | 可验证性 | 举例 |
|---|---|---|---|---|
| 指令 | Dir | 设计层面的要求,描述“应该做什么” | 通常无法静态检查,需要人工评审 | Dir 4.1:运行期行为必须可预测 |
| 规则 | Rule | 编码层面的约束,描述“不能怎么写” | 通常可被静态分析工具自动检查 | Rule 10.1:操作数不能有不合法的基本类型 |
编号格式上,Dir和Rule都采用“大类.序号”的方式。比如Rule 10.1,10是类型转换大类,1是该大类下的第一条规则。这种设计让你一眼就知道规则归属哪个主题域。
3.2 规则分组:三个层面
MISRA C 2012把规则分成三大组。我把它总结为“语言层面、编程实践、文档要求”。这三层从语法到习惯到管理,层层递进。
3.2.1 语言层面(Language Level)
这部分规则直接约束C语言的语法和语义。说白了,就是告诉你“C语言这个特性别乱用”。比如:
- 类型转换(Rule 10.x系列):隐式转换、整型提升、指针转换
- 表达式(Rule 12.x系列):副作用、求值顺序、运算符优先级
- 控制流(Rule 14.x系列):if-else配对、switch穿透、循环终止
if (a = b) 做赋值判断。Rule 13.2明确禁止这种“赋值作为布尔值”的写法。工具能扫出来,但前提是你开了这条规则。
3.2.2 编程实践(Programming Practice)
这一层更偏向“怎么写代码更安全”。它不直接说语法错误,而是约束编码习惯。比如:
- 命名与注释(Dir 4.x系列):标识符不能重复、注释不能嵌套
- 函数设计(Rule 8.x系列):函数参数个数限制、返回值必须使用
- 内存管理(Rule 22.x系列):动态内存分配限制、指针使用规范
我个人觉得,编程实践类规则是团队最容易“讨价还价”的地方。比如Rule 8.2要求函数参数不超过6个,有人觉得太死板。但我在一个通信协议栈项目里,见过一个函数有12个参数,调试时根本记不清顺序——后来重构时拆成3个结构体,bug率直接降了一半。
3.2.3 文档要求(Documentation Requirement)
这类规则不直接管代码,而是管“你写代码时留下的记录”。比如:
- 偏差记录(Dir 4.12):如果违反某条规则,必须记录理由和审批
- 工具配置(Dir 4.13):静态分析工具的配置必须文档化
- 编译器行为(Dir 4.14):依赖编译器特定扩展时必须说明
3.3 规则优先级与严重性矩阵
MISRA C把每条规则按“必须遵守”和分了两个层级。但实际项目中,我更喜欢用“严重性 × 可能性”矩阵来排优先级。下面这张表是我自己整理的,供你参考:
| 优先级 | 严重性 | 违反后果 | 典型规则举例 | 我的建议 |
|---|---|---|---|---|
| P0(致命) | 高 | 可能导致系统崩溃、安全失效 | Rule 1.3(未定义行为)、Rule 18.1(指针算术越界) | 零容忍,工具必须阻断编译 |
| P1(严重) | 高 | 可能导致数据损坏、逻辑错误 | Rule 10.1(非法类型转换)、Rule 13.2(赋值当布尔) | 必须修复,评审重点 |
| P2(中等) | 中 | 可能导致可维护性下降、偶发bug | Rule 8.2(参数过多)、Rule 15.5(switch无default) | 建议修复,可申请偏差 |
| P3(低) | 低 | 风格问题,不影响功能 | Rule 4.1(八进制常量)、Rule 5.1(标识符长度) | 团队约定即可,审计时说明 |
3.4 知识体系总览图
下面这张SVG图,把规则分类的整个骨架画出来了。你可以把它当成“MISRA C规则地图”贴在工位上。
3.5 如何用这套体系做合规整改
有了上面的地图,你拿到一份代码后,可以按这个步骤来:
- 先扫P0/P1的Rule:用静态分析工具(比如PC-lint、Coverity)跑一遍,把致命和严重问题全部列出来。
- 再查Dir类指令:人工评审设计文档和代码,看有没有违反Dir 4.1(可预测性)、Dir 4.12(偏差记录)等。
- 最后过P2/P3:根据项目安全等级决定是否全部整改。如果时间紧,可以申请偏差,但必须记录理由。