# Misra C++ 2008 详细总结


# MISRA C++:2008 详细总结
MISRA C++:2008 全称《Guidelines for the use of the C++ language in critical systems》，是由英国汽车工业软件可靠性协会（MISRA）于2008年发布的**C++安全编码行业标准**，专为高安全、高可靠性要求的嵌入式与关键系统设计，是全球汽车电子、航空航天、医疗设备、轨道交通、工业控制等领域公认的C++编码事实规范，也是ISO 26262、IEC 61508、DO-178C等国际功能安全标准在C++语言层面的核心落地支撑。

## 一、基础核心信息
1.  **适用语言标准**：严格基于ISO/IEC 14882:2003（C++03标准，含TC1技术勘误），不兼容C++11及之后的现代C++标准。
2.  **核心目标**：系统性约束C++语言中易引发**未定义行为、内存错误、类型不安全、异常不可控、资源泄漏、可移植性缺陷**的特性，在研发生命周期早期消除编码缺陷，降低系统运行时失效与安全事故风险。
3.  **规则总量**：总计228条结构化编码规则，覆盖C++全语言特性与开发全流程，按强制约束力分为三大类：
    | 规则类别 | 核心定义 | 合规要求 |
    |---|---|---|
    | Required（必要/强制） | 强制性开发要求 | 声称合规的代码必须100%遵守；违反必须提交**正式签字审批的偏差记录**，所有Required规则权重平等 |
    | Advisory（建议） | 推荐性最佳实践 | 无强制合规效力，无需正式偏差流程，但不允许随意忽略，应尽可能遵循 |
    | Document（文档） | 过程性强制要求 | 当代码使用相关特性时，必须完成书面记录与说明，不允许偏差，多为难以通过静态工具自动检测的要求 |

## 二、完整章节与核心规则体系
MISRA C++:2008 按C++语言语法与开发逻辑分为17个核心章节（编号0~27，覆盖全语言维度），各章节核心约束与代表性规则如下：

### 第0章 语言独立性问题
通用顶层原则，是所有规则的基础，共4个子类：
1.  **不必要的结构**：核心约束代码冗余与无效逻辑，共12条强制规则，全面禁止**不可达代码、死代码、未使用变量/函数/类型、未使用的函数返回值、未使用的函数参数**，要求代码极简且无冗余。
2.  **存储约束**：禁止对象赋值给重叠的内存对象，防止内存覆盖引发的未定义行为。
3.  **运行时错误防护**：要求必须通过静态分析、动态分析或显式编码检查三种方式之一管控运行时故障；函数返回的错误信息必须被检测处理，禁止忽略错误返回值。
4.  **算法约束**：定点/浮点算法的使用必须书面记录，浮点实现必须遵循定义的浮点标准。

### 第1章 通用规则
- 强制所有代码必须符合C++03标准，禁止使用编译器非标准扩展；
- 多编译器联合使用时，必须记录编译器的公共定义接口；
- 必须确定并记录编译器的整数除法实现行为，消除平台差异。

### 第2章 词法约定
覆盖C++词法层面的安全约束，核心规则包括：
- 禁止使用三字符序列，不推荐使用有向图，避免词法解析歧义；
- 禁止用C风格注释嵌套代码段，不推荐用C++行注释嵌套代码；
- 标识符必须具备排版唯一性，禁止内层作用域标识符隐藏外层作用域同名标识符；
- 禁止使用八进制常量（0除外）和八进制转义序列，无符号整型常量必须加U后缀，数值后缀必须大写；
- 禁止窄字符串与宽字符串字面量拼接。

### 第3章 基本概念
围绕C++核心语法规则的约束，核心包括：
- 严格遵守单定义规则（ODR），禁止跨编译单元违反ODR；
- 禁止在块作用域内声明函数，头文件中禁止声明具有外部链接的对象或函数；
- 标识符必须在最小可见性的块中定义，最小化变量作用域；
- 推荐使用带明确大小和符号的typedef替代基础数值类型，提升可移植性；
- 禁止直接操作浮点值的底层位表示。

### 第4章 标准转换
约束C++隐式/显式类型转换的安全风险，核心包括：
- 严格限制bool、枚举、char/wchar_t类型的运算符使用场景，仅允许用于语义匹配的内置运算符；
- 禁止将NULL用作整数值，禁止将0用作非指针常量，明确空指针与0值的语义边界。

### 第5章 表达式
针对表达式求值的未定义行为与歧义做全面约束，核心包括：
- 表达式的值必须在标准允许的所有求值顺序下保持一致，禁止依赖运算符求值顺序的写法；
- 禁止隐式转换改变整型符号位，禁止隐式浮点-整型互转，禁止隐式转换缩小类型宽度；
- 条件判断（if/for/while/三目运算符）的条件必须是bool类型，禁止用整型/指针直接作为判断条件；
- 数组索引是唯一允许的指针算术形式，禁止其他指针加减运算；
- 移位运算符的右操作数必须在0到左操作数类型位宽之间，禁止越界移位。

### 第6章 语句
控制流语句的安全约束，核心包括：
- 禁止在子表达式中使用赋值运算符，避免if(a=b)这类歧义写法；
- if/else/for/while等结构必须后跟复合语句（大括号包裹），禁止单行无括号语句；
- switch语句必须包含default分支，每个case分支必须有break/return等显式终止语句，禁止case穿透；
- for循环必须有明确的循环计数器，且计数器不能是浮点类型；
- 函数必须有唯一的退出点，禁止多return分支分散函数退出逻辑；
- 严格限制goto语句的使用，仅允许在同一块或嵌套块内跳转，禁止跳转到try/catch块内。

### 第7-8章 声明与定义
围绕变量、函数、类型的声明与定义的约束，核心包括：
- 无需修改的变量必须加const限定，函数入参的只读对象必须声明为const指针/引用；
- 全局命名空间仅允许包含main函数、命名空间声明和extern声明，禁止污染全局命名空间；
- 头文件中禁止使用未命名命名空间，禁止使用using namespace指令；
- 禁止函数返回局部变量的指针/引用，禁止返回入参的临时引用/指针；
- 禁止使用可变参数函数（ellipsis），所有函数必须有完整的原型声明；
- 所有变量使用前必须初始化，数组/结构体初始化必须用大括号匹配结构；
- 枚举类型的显式初始化必须全量显式赋值，禁止部分赋值。

### 第9-12章 类与面向对象特性
针对C++面向对象核心特性的安全约束，是MISRA C++:2008的核心重点，核心包括：
- 非POD类型的类成员数据必须声明为private，严格封装类内部状态；
- const成员函数禁止返回类成员的非常量指针/引用，防止const语义被破坏；
- 成员函数能声明为static/const的，必须声明为对应的类型；
- 禁止使用联合体（union），避免类型双关引发的未定义行为；
- 位域必须是bool或显式signed/unsigned整型，禁止用枚举类型定义位域，有符号位域长度必须大于1位；
- 禁止在构造/析构函数中使用对象的动态类型，禁止构造/析构中调用虚函数；
- 单参数构造函数必须声明为explicit，禁止隐式类型转换；
- 菱形继承中的基类必须声明为虚基类，同一基类禁止同时作为虚基类和非虚基类；
- 重写虚函数必须显式加virtual关键字，纯虚函数只能被纯虚函数重写；
- 抽象类的拷贝赋值运算符必须声明为protected/private，禁止切片赋值。

### 第14章 模板
针对C++模板特性的安全约束，核心包括：
- 模板构造函数/模板赋值运算符存在时，必须显式声明拷贝构造函数/拷贝赋值运算符，避免编译器生成的默认函数不符合预期；
- 带从属基类的类模板，基类中的名称必须用qualified-id或this->显式引用，避免名字解析歧义；
- 所有模板必须至少实例化一次，确保模板代码无语法与逻辑缺陷；
- 模板的显式特化必须与主模板声明在同一文件中，禁止跨文件特化；
- 禁止显式特化重载函数模板。

### 第15章 异常处理
针对C++异常机制的全流程安全约束，核心包括：
- 异常仅允许用于错误处理，禁止用于常规流程控制，使用场景必须书面记录；
- 禁止用goto/switch跳转到try/catch块内，throw表达式本身禁止抛出异常；
- 类类型异常必须通过引用捕获，catch处理程序必须按从派生类到基类的顺序排列，catch(...)必须放在最后；
- 析构函数绝对不允许抛出异常，避免栈展开过程中程序终止；
- 代码中显式抛出的所有异常，必须在调用路径上有对应的兼容类型处理程序；
- 函数异常规范的所有声明必须完全一致，禁止隐式调用terminate()函数。

### 第16章 预处理指令
针对C++预处理器的约束，核心包括：
- #include指令之前仅允许出现其他预处理指令或注释；
- 宏定义/取消仅允许在全局命名空间中进行，禁止使用#undef；
- 禁止定义函数式宏，优先用const、枚举、内联函数替代宏；
- 所有#pragma指令的使用必须书面记录。

### 第17-27章 标准库约束
针对C++标准库的使用安全做全面限制，核心包括：
- 禁止定义、重定义、取消标准库的保留标识符、宏与函数，禁止复用标准库名称；
- 必须使用C++版本的C兼容库（如<cstdio>而非<stdio.h>）；
- 禁止使用setjmp/longjmp，禁止使用信号处理设施<csignal>；
- 禁止使用动态堆内存分配（new/delete、malloc/free），规避内存泄漏与碎片风险；
- 禁止使用atoi/atof/atol、abort/exit/system、无边界字符串函数（strcpy/strcat等）；
- 禁止使用errno错误指示器，禁止使用C风格IO库<cstdio>；
- 禁止使用<ctime>的时间处理函数。

## 三、合规性核心要求
### 1. 合规声明的必备条件
声称代码符合MISRA C++:2008，必须同时满足以下要求：
1.  完成合规矩阵，明确每条规则的检查方式（静态工具/人工评审）；
2.  所有代码符合全部Required规则，或对违反项完成正式的偏差记录；
3.  维护完整的规则违反清单，每条违反项都有经签字审批的偏差说明；
4.  完成编译器选型与验证、工具链验证、开发人员培训、测试覆盖等配套流程的文档记录。

### 2. 偏差管理规范
- 仅Required规则需要正式偏差流程，偏差必须包含：规则编号、违反原因、风险评估、缓解措施、审批签字、有效期；
- 偏差必须基于项目具体场景，禁止批量豁免规则，所有偏差必须可追溯；
- Document类规则不允许偏差，只要使用相关特性，必须完成书面记录。

### 3. 工具与流程要求
- 优先使用商业静态代码分析工具（SAST）实现规则自动化检查，工具必须经过验证，确保规则检测的准确性；
- 无法通过工具自动检测的规则，必须制定标准化的人工评审流程，留存评审记录；
- 合规检查必须嵌入CI/CD流水线，在代码提交、构建、发布环节执行门禁检查。

## 四、行业价值与演进
### 1. 核心应用价值
- 是汽车电子ECU、ADAS、BMS等安全相关系统的强制准入规范，是ISO 26262功能安全认证的核心语言层面支撑；
- 大幅降低C++代码的未定义行为与运行时故障，提升代码的可读性、可维护性与可移植性；
- 建立了统一的C++安全编码基线，降低团队协作与代码交接的成本，减少长期技术债务。

### 2. 局限性与后续演进
1.  **核心局限性**：仅支持C++03标准，无法覆盖C++11及之后的现代C++特性（智能指针、lambda、移动语义、constexpr等），无法适配现代C++开发需求。
2.  **后续标准演进**：
    - **AUTOSAR C++14**：基于MISRA C++:2008扩展，适配C++14标准，是Adaptive AUTOSAR平台的核心编码规范，广泛应用于现代汽车电子开发；
    - **MISRA C++:2023**：MISRA官方发布的新一代C++安全编码标准，适配C++17标准，全面替代MISRA C++:2008，兼容现代C++特性，同时继承了原标准的安全核心思想。


