目录

Misra C++ 2023 规范

MISRA C++ 2023

https://ww2.mathworks.cn/help/bugfinder/misra-cpp-2023-rules-and-directives.html?lang=en

English Version


语言无关问题

[规则 0.0.1 必需] 函数不得包含不可达语句。

[规则 0.0.2 建议] 控制表达式不应是不变的。

[规则 0.1.1 建议] 不应不必要地向局部对象写入值。

[规则 0.1.2 必需] 函数返回的值应当被使用。

[规则 0.2.1 建议] 具有有限可见性的变量应至少使用一次。

[规则 0.2.2 必需] 命名的函数参数应至少使用一次。

[规则 0.2.3 建议] 具有有限可见性的类型应至少使用一次。

[规则 0.2.4 建议] 具有有限可见性的函数应至少使用一次。

[指南 0.3.1 建议] 应适当地使用浮点运算。

[指南 0.3.2 必需] 函数调用不得违反函数的前置条件。


一般原则

[规则 4.1.1 建议] 程序应符合 ISO/IEC 14882:2017 (C++17)。

[规则 4.1.2 必需] 不应使用已弃用的特性。

[规则 4.1.3 必需] 不得出现未定义或关键未指定行为。

[规则 4.6.1 必需] 对内存位置的操作应适当排序。


词法约定

[规则 5.0.1 建议] 不应使用类似三字符序列。

[规则 5.7.1 必需] C 风格注释内不得使用 /* 字符序列。

[指南 5.7.2 建议] 代码段不应被"注释掉"。

[规则 5.7.3 必需] 在 // 注释中不得使用行拼接。

[规则 5.10.1 必需] 用户定义标识符应具有适当的形式。

[规则 5.13.1 必需] 在字符字面量和非原始字符串字面量中,\ 只能用于形成已定义的转义序列或通用字符名。

[规则 5.13.2 必需] 八进制转义序列、十六进制转义序列和通用字符名应被终止。

[规则 5.13.3 必需] 不得使用八进制常量。

[规则 5.13.4 必需] 无符号整数字面量应适当添加后缀。

[规则 5.13.5 必需] 小写形式的 L 不得用作字面量后缀的第一个字符。

[规则 5.13.6 必需] 类型为 long long 的整数字面量在任何后缀中不得仅使用单个 Ll

[规则 5.13.7 必需] 具有不同编码前缀的字符串字面量不得连接。


基本概念

[规则 6.0.1 必需] 块作用域声明不得在视觉上产生歧义。

[规则 6.0.2 建议] 声明具有外部链接的数组时,应显式指定其大小。

[规则 6.0.3 建议] 全局命名空间中唯一的声明应为主函数 main、命名空间声明和 extern "C" 声明。

[规则 6.0.4 必需] 标识符 main 不得用于除全局函数 main 以外的其他函数。

[规则 6.2.1 必需] 不得违反单一定义规则。

[规则 6.2.2 必需] 变量或函数的所有声明应具有相同的类型。

[规则 6.2.3 必需] 实现实体的源代码应仅出现一次。

[规则 6.2.4 必需] 头文件不得包含具有外部链接的非内联函数或对象的定义。

[规则 6.4.1 必需] 内层作用域中声明的变量不得隐藏外层作用域中声明的变量。

[规则 6.4.2 必需] 派生类不得隐藏从基类继承的函数。

[规则 6.4.3 必需] 依赖基类中存在的名称不得通过非限定查找解析。

[规则 6.5.1 建议] 具有外部链接的函数或对象应在头文件中引入。

[规则 6.5.2 建议] 应适当地指定内部链接。

[规则 6.7.1 必需] 局部变量不得具有静态存储期限。

[规则 6.7.2 必需] 不得使用全局变量。

[规则 6.8.1 必需] 不得在对象生命周期之外访问该对象。

[规则 6.8.2 强制] 函数不得返回具有自动存储期限的局部变量的引用或指针。

[规则 6.8.3 必需] 赋值运算符不得将具有自动存储期限的对象的地址赋给具有更长生命周期的对象。

[规则 6.8.4 建议] 返回对其对象引用的成员函数应适当地使用引用限定符。

[规则 6.9.1 必需] 同一实体的所有声明应使用相同类型别名。

[规则 6.9.2 建议] 不应使用标准有符号整数类型和标准无符号整数类型的名称。


标准约定

[规则 7.0.1 必需] 不得从 bool 类型进行转换。

[规则 7.0.2 必需] 不得转换为 bool 类型。

[规则 7.0.3 必需] 不得使用字符的数值。

[规则 7.0.4 必需] 位运算符和移位运算符的操作数应适当。

[规则 7.0.5 必需] 整数提升和常规算术转换不得改变操作数的符号性或类型类别。

[规则 7.0.6 必需] 数值类型之间的赋值应适当。

[规则 7.11.1 必需] nullptr 应是空指针常量的唯一形式。

[规则 7.11.2 必需] 作为函数参数传递的数组不得退化为指针。

[规则 7.11.3 必需] 从函数类型到指向函数类型的指针的转换仅应在适当上下文中发生。


表达式

[规则 8.0.1 建议] 应使用括号使表达式的含义适当明确。

[规则 8.1.1 必需] 非临时 lambda 不得隐式捕获 this

[规则 8.1.2 建议] 非临时 lambda 中应显式捕获变量。

[规则 8.2.1 必需] 虚基类只能通过 dynamic_cast 转换为派生类。

[规则 8.2.2 必需] 不得使用 C 风格强制转换和函数表示法强制转换。

[规则 8.2.3 必需] 强制转换不得从通过指针或引用访问的类型中移除任何 constvolatile 限定。

[规则 8.2.4 必需] 不得在指向函数的指针和其他任何类型之间执行强制转换。

[规则 8.2.5 必需] 不得使用 reinterpret_cast

[规则 8.2.6 必需] 具有整数、枚举或指向 void 类型对象不得强制转换为指针类型。

[规则 8.2.7 建议] 强制转换不应将指针类型转换为整数类型。

[规则 8.2.8 必需] 对象指针类型不得强制转换为除 std::uintptr_tstd::intptr_t 以外的整数类型。

[规则 8.2.9 必需] typeid 的操作数不得是多态类类型的表达式。

[规则 8.2.10 必需] 函数不得直接或间接调用自身。

[规则 8.2.11 必需] 通过省略号传递的参数应具有适当类型。

[规则 8.3.1 建议] 内置一元 - 运算符不应应用于无符号类型的表达式。

[规则 8.3.2 建议] 内置一元 + 运算符不应使用。

[规则 8.7.1 必需] 指针运算不得形成无效指针。

[规则 8.7.2 必需] 指针之间的减法仅应应用于指向同一数组元素的指针。

[规则 8.9.1 必需] 内置关系运算符 >>=<<= 不应应用于指针类型的对象,除非它们指向同一数组的元素。

[规则 8.14.1 建议] 逻辑 &&|| 运算符的右操作数不应包含持久副作用。

[规则 8.18.1 强制] 对象或子对象不得复制到重叠对象。

[规则 8.18.2 建议] 赋值运算符的结果不应被使用。

[规则 8.19.1 建议] 逗号运算符不应使用。

[规则 8.20.1 建议] 具有常量操作数的无符号算术运算不应溢出。


语句

[规则 9.2.1 必需] 显式类型转换不应是表达式语句。

[规则 9.3.1 必需] 迭代语句或选择语句的主体应是复合语句。

[规则 9.4.1 必需] 所有 if ... else if 结构应以 else 语句终止。

[规则 9.4.2 必需] switch 语句的结构应适当。

[规则 9.5.1 必需] 传统 for 语句应简单。

[规则 9.5.2 必需] for-range-initializer 应包含最多一个函数调用。

[规则 9.6.1 建议] 应不使用 goto 语句。

[规则 9.6.2 必需] goto 语句应引用周围块中的标签。

[规则 9.6.3 必需] goto 语句应跳转到函数体中稍后声明的标签。

[规则 9.6.4 必需] 声明了 [[noreturn]] 属性的函数不应返回。

[规则 9.6.5 必需] 非 void 返回类型的函数应在所有路径上返回值。


声明

[规则 10.0.1 建议] 声明不应声明多个变量或成员变量。

[规则 10.1.1 建议] 指针或左值引用参数的目标类型应适当 const 限定。

[规则 10.1.2 必需] 应适当使用 volatile 限定。

[规则 10.2.1 必需] 枚举应使用显式底层类型定义。

[规则 10.2.2 建议] 不应声明无作用域枚举。

[规则 10.2.3 必需] 不应使用没有固定底层类型的无作用域枚举的数值。

[规则 10.3.1 建议] 头文件中不应有未命名命名空间。

[规则 10.4.1 必需] 不应使用 asm 声明。


声明符

[规则 11.3.1 建议] 不应声明数组类型的变量。

[规则 11.3.2 建议] 对象声明不应包含超过两级指针间接。

[规则 11.6.1 建议] 所有变量应被初始化。

[规则 11.6.2 强制] 在对象被设置之前,其值不得被读取。

[规则 11.6.3 必需] 在枚举列表中,隐式指定的枚举常量的值应唯一。


[规则 12.2.1 建议] 不应声明位域。

[规则 12.2.2 必需] 位域应具有适当类型。

[规则 12.2.3 必需] 具有有符号整数类型的命名位域不应具有一个比特的长度。

[规则 12.3.1 必需] 不应使用 union 关键字。

[规则 12.3.1 必需] 不应使用 union 关键字。


派生类

[规则 13.1.1 建议] 类不应被虚继承。

[规则 13.1.2 必需] 可访问的基类不应在同一层次结构中既是 virtual 的又是非 virtual 的。

[规则 13.3.1 必需] 用户声明的成员函数应适当使用 virtualoverridefinal 限定符。

[规则 13.3.2 必需] 重写虚函数中的参数不应指定不同的默认参数。

[规则 13.3.3 必需] 函数的所有声明或重写中的参数应要么是未命名的,要么具有相同的名称。

[规则 13.3.4 必需] 潜在虚指针到成员函数的比较应仅与 nullptr 进行。


成员访问控制

[规则 14.1.1 建议] 非静态数据成员应全部为 private 或全部为 public


特殊成员函数

[规则 15.0.1 必需] 应适当提供特殊成员函数。

[规则 15.0.2 建议] 类的用户提供的复制和移动成员函数应具有适当签名。

[规则 15.1.1 必需] 不应从对象的构造函数或析构函数中使用其动态类型。

[规则 15.1.2 建议] 类的所有构造函数应显式初始化其所有虚基类和直接基类。

[规则 15.1.3 必需] 可使用单个参数调用的转换运算符和构造函数应为显式。

[规则 15.1.4 建议] 类的所有直接、非静态数据成员应在类对象可访问之前被初始化。

[规则 15.1.5 必需] 类应仅在其唯一构造函数时定义初始化列表构造函数。

[指南 15.8.1] 用户提供的复制赋值运算符和移动赋值运算符应处理自赋值。


重载

[规则 16.5.1 必需] 不应重载逻辑与 && 和逻辑或 || 运算符。

[规则 16.5.2 必需] 不应重载 address-of 运算符。

[规则 16.6.1 建议] 对称运算符应仅作为非成员函数实现。


模板

[规则 17.8.1 必需] 不应显式特化函数模板。


异常处理

[规则 18.1.1 必需] 异常对象不应具有指针类型。

[规则 18.1.2 必需] 空的 throw 仅应在 catch 处理程序的复合语句中发生。

[规则 18.3.1 建议] 应至少有一个异常处理程序来捕获所有其他未处理的异常。

[规则 18.3.2 必需] 类类型的异常应通过 const 引用或引用捕获。

[规则 18.3.3 必需] 构造函数或析构函数的 function-try-block 的处理程序不应引用其类或其基类的非静态成员。

[规则 18.4.1 必需] 异常不友好的函数应为 noexcept

[规则 18.5.1 建议] 不应尝试将 noexcept 函数的异常传播到调用函数。

[规则 18.5.2 建议] 不应使用程序终止函数。


预处理指令

[规则 19.0.1 必需] 以 # 作为第一个标记的行应为有效的预处理指令。

[规则 19.0.2 必需] 不应定义函数式宏。

[规则 19.0.3 建议] #include 指令前面应仅由预处理指令或注释。

[规则 19.0.4 建议] #undef 应仅用于在相同文件中先前定义的宏。

[规则 19.1.1 必需] 应适当使用 defined 预处理器运算符。

[规则 19.1.2 必需] 所有 #else#elif#endif 预处理指令应与相关的 #if#ifdef#ifndef 指令位于同一文件中。

[规则 19.1.3 必需] #if#elif 预处理指令的控制表达式中使用的所有标识符应在评估之前被定义。

[规则 19.2.1 必需] 应采取预防措施,以防止头文件的内容被包含多次。

[规则 19.2.2 必需] #include 指令后面应跟随 <filename>"filename" 序列。

[规则 19.2.3 必需] '"\ 字符和 /*// 字符序列不应出现在头文件名中。

[规则 19.3.1 建议] 不应使用 ### 预处理器运算符。

[规则 19.3.2 必需] 紧跟 # 运算符的宏参数不应立即跟随 ## 运算符。

[规则 19.3.3 必需] 混合使用宏参数的参数不应被进一步展开。

[规则 19.3.4 必需] 应使用括号以确保宏参数被适当展开。

[规则 19.3.5 必需] 看起来像预处理指令的标记不应出现在宏参数中。

[规则 19.6.1 建议] 不应使用 #pragma 指令和 _Pragma 运算符。


语言支持库

[规则 21.2.1 必需] 不应使用 <cstdlib> 中的库函数 atofatoiatolatoll

[规则 21.2.2 必需] 不应使用 <cstring><cstdlib><cwchar><cinttypes> 中的字符串处理函数。

[规则 21.2.3 必需] 不应使用 <cstdlib> 中的库函数 system

[规则 21.2.4 必需] 不应使用宏 offsetof

[规则 21.6.1 建议] 不应使用动态内存。

[规则 21.6.2 必需] 动态内存应自动管理。

[规则 21.6.3 必需] 不应使用高级内存管理。

[规则 21.6.4 必需] 如果项目定义了全局运算符 delete 的有大小或无大小版本,则两者都应被定义。

[规则 21.6.5 必需] 不应删除不完整类类型的指针。

[规则 21.10.1 必需] 不应使用 <cstdarg> 的功能。

[规则 21.10.2 必需] 不应使用标准头文件 <csetjmp>

[规则 21.10.3 必需] 不应使用标准头文件 <csignal> 提供的功能。


诊断库

[规则 22.3.1 必需] 不应使用常量表达式作为 assert 宏的参数。

[规则 22.4.1 必需] 字面值零应是赋给 errno 的唯一值。


通用工具库

[规则 23.11.1 必需] 不应使用 std::shared_ptrstd::unique_ptr 的原始指针构造函数。


字符串库

[规则 24.5.1 必需] 不应使用 <cctype><cwctype> 中的字符处理函数。

[规则 24.5.2 必需] 不应使用 <cstring> 中的 C++ 标准库函数 memcpymemmovememcmp


本地化库

[规则 25.5.1 必需] 不应调用 setlocalestd::locale::global 函数。

[规则 25.5.2 强制] 由 C++ 标准库函数 localeconvgetenvsetlocalestrerror 返回的指针必须仅被用作具有 const 限定类型的指针。

[规则 25.5.3 强制] 由 C++ 标准库函数 asctimectimegmtimelocaltimelocaleconvgetenvsetlocalestrerror 返回的指针在后续调用相同函数后不得被使用。


容器库

[规则 26.3.1 建议] std::vector 不应使用 bool 进行特化。


算法库

[规则 28.3.1 必需] 谓词不应具有持久副作用。

[规则 28.6.1 必需] std::move 的参数应是非 const 左值。

[规则 28.6.2 必需] 转发引用和 std::forward 应一起使用。

[规则 28.6.3 必需] 对象不应在其可能被移动的状态下使用。

[规则 28.6.4 必需] 应使用 std::removestd::remove_ifstd::uniqueempty 的结果。


输入/输出库

[规则 30.0.1 必需] 不应使用 C 库输入/输出函数。

[规则 30.0.2 必需] 同一文件流上的读取和写入应由定位操作分隔。


English Version