2. 编码标准与航空安全
在航空机载软件中,编码标准不是“风格偏好”,而是把适航安全目标落到每一行代码上的约束手段。DO-178C 要求软件满足其目标与 DAL 等级,但标准本身并不规定“怎么写 C 语言”;MISRA C/C++、CERT C/C++、JSF AV C++ 等编码标准正是把“可验证、可追溯、可审查”的安全意图翻译成可检查条款的中间层。理解它们的条款结构、安全目标与裁剪方法,是静态分析工具配置和适航审查证据准备的前提。
三类标准的定位差异
MISRA C 起源于汽车行业,但因其对 C 语言“未定义行为、实现定义行为、易错构造”的系统性梳理,被航空领域广泛借用。它按“强制(Required)、建议(Advisory)、文档(Document)”分级,条款编号如 Dir 4.1、Rule 10.3、Rule 17.7,覆盖类型转换、指针、控制流、内存等主题。MISRA C++ 与 MISRA C:2023 延续了同样的“可判定性优先”思路:能静态判定的写成规则,难以判定的写成指令(Directive)。
CERT C/C++ 由 SEI 维护,更强调“安全后果”而非“语言子集”。它把条款组织为规则(Rule)和建议(Recommendation),并按风险领域分类,如 EXP(表达式)、INT(整数)、MEM(内存)、STR(字符串)。CERT 的条款往往直接对应可利用漏洞,例如 INT30-C 防止无符号整数回绕、MEM35-C 防止未对齐访问。它的安全目标偏向“避免可被攻击者利用的缺陷”,与航空的“避免功能失效”形成互补。
JSF AV C++ 来自联合攻击战斗机项目,是一份面向 C++ 的航空编码规范,条款以 AV Rule 编号,强调限制 C++ 中难以验证的特性:禁止多重继承、限制模板、禁止异常、限制动态内存、要求可预测的构造与析构。它的安全目标是“让 C++ 代码可被静态分析和形式化验证”,因此条款更偏向语言子集裁剪,而非逐条漏洞防护。
条款结构:从“可判定”到“可审查”
三类标准的条款结构都遵循一个共同逻辑:把安全意图拆成可判定的原子命题。MISRA 的 Rule 10.3 要求“表达式的值不应赋给更宽或更窄的基本类型”,这条规则可以被静态分析器直接判定;而 Dir 4.1 要求“应最小化运行时失败”,则属于指令,需要设计文档和评审记录来支撑。CERT 的 INT30-C 给出具体判定条件:无符号整数运算不得回绕,工具可检查减法、乘法、加法。JSF AV Rule 206 禁止在构造函数中调用虚函数,工具可检查调用图。
这种“可判定性”直接决定了审查方式:规则类条款由工具自动检查并生成报告,指令类条款由人工评审和文档证据支撑。适航审查时,审查员会要求看到“条款—工具—证据”的映射表,而不是一句“我们遵循 MISRA”。
合规裁剪:不是删条款,而是做安全论证
裁剪(Tailoring)是航空编码标准落地的关键动作。DAL A 软件通常要求 MISRA C 全部强制条款,DAL C 可对部分建议条款做偏离。裁剪不是简单删除,而是对每条偏离给出:偏离理由、替代措施、影响分析、验证证据。例如某项目使用 MISRA C:2012 Rule 11.3(禁止指针类型转换),但底层驱动需要访问寄存器地址,于是申请偏离,替代措施是“所有指针转换集中在 HAL 层,并由单元测试覆盖地址对齐与边界”。
裁剪结果应写入 PSAC(计划 for 软件合格审定)和 SAS(软件成就总结)。审查员关注的是:裁剪是否有据、是否可追溯、是否影响 DAL 目标。一个常见的裁剪表字段包括:条款编号、标准来源、DAL 适用性、裁剪决定、理由、替代措施、验证方法、责任人。
标准与适航审查的对应关系
DO-178C 表 A-1 到 A-10 列出了软件生命周期目标,其中与编码标准直接相关的是 A-2(软件设计标准)、A-5(源代码符合标准)、A-6(源代码可追溯)。编码标准是满足 A-5 的手段:工具检查报告证明源代码符合标准;偏差记录证明不符合项已被处理。A-6 要求代码可追溯至低层需求,编码标准中的命名、注释、模块化条款为此提供支撑。
工具鉴定(DO-330)是另一个对应点:如果静态分析工具用于替代人工评审,需按 TQL 等级鉴定。例如用工具检查 MISRA 规则,工具本身需证明其判定结果可信。审查员会检查工具鉴定材料、误报/漏报评估、以及工具版本与配置的冻结记录。
一个可参考的裁剪决策示例
假设某 DAL B 飞控软件使用 C 语言,选择 MISRA C:2012 作为主标准,CERT C 作为补充。裁剪决策如下:
| 条款 | 来源 | DAL B 决定 | 理由与替代措施 |
|---|---|---|---|
| Rule 10.3 | MISRA C | 强制 | 类型转换风险高,工具自动检查 |
| Rule 17.7 | MISRA C | 强制 | 返回值未使用可能导致错误遗漏 |
| Dir 4.1 | MISRA C | 强制 | 运行时失败最小化,需设计评审 |
| INT30-C | CERT C | 强制 | 无符号回绕可被利用,工具检查 |
| Rule 11.3 | MISRA C | 偏离 | HAL 层寄存器访问,集中管理并单元测试 |
| Rule 21.3 | MISRA C | 偏离 | 使用经鉴定的内存分配库,替代措施为静态分配 |
该表可直接作为裁剪申请的基础,审查时附上工具报告和单元测试记录。注意:偏离条款必须逐条论证,不能批量“豁免”。
常见误区与排障
误区一:把 MISRA 当成“必须全部遵守”。实际上 MISRA 允许偏离,但偏离必须有安全论证。误区二:只配置工具不建矩阵。工具报告只能证明“检查了什么”,不能证明“为什么这些条款适用”。误区三:忽略 CERT 与 MISRA 的重叠。两者在整数、指针、内存主题上有重叠,裁剪时应去重,避免重复劳动。误区四:JSF AV C++ 直接套用到 C 项目。JSF 是 C++ 规范,C 项目应优先 MISRA C 和 CERT C。
排障时,若工具报告大量误报,先检查规则配置是否与裁剪表一致;若审查员质疑裁剪,检查偏离记录是否有替代措施和验证证据;若追溯断裂,检查编码标准中的命名与注释条款是否被执行。
总结来看,MISRA、CERT、JSF AV C++ 分别从“语言子集约束”“漏洞防护”“可验证性”三个角度服务航空安全。条款结构决定检查方式,安全目标决定裁剪尺度,适航审查决定证据形态。把三者对齐,才能让编码标准真正成为适航证据链的一部分,而不是一份束之高阁的规范文档。