MISRA C++ 2008 标准解析

2023-12-13 17:54:02

MISRA C++ 2008是《汽车专用软件的C++语言编程指南》,是针对C++语言的安全编码标准,适用C++ 03标准,是汽车行业公认的C++语言编码规范,目的是在研发生命周期早期发现软件中的缺陷,预防成本投入会大幅度降低投产后的售后维护成本。

?MISRA C++ 2008主要是功能安全,共有规则228条。划分一级分类和二级分类,按照是否强制执行分为三个类别:文档、必要和建议。文档相当于MISRA C 2008中的指令类别,大多是一些编程要求,比较难于通过SAST技术实现。

分类子类编号类别规则项支持启用
语言独立性问题不必要的结构M0-1-1必要项目不应包含无法到达的代码
M0-1-2必要项目不应包含不可达的路径
M0-1-3必要项目不应包含未使用的变量
M0-1-4必要项目不应包含只使用一次的非”volatile POD“变量
M0-1-5必要项目不应包含未使用的类型声明
M0-1-6必要项目不应包含被赋予之后绝不会使用的值的非volatile变量的实例
M0-1-7必要应始终使用不是重载运算符的返回类型为非void的函数返回值
M0-1-8必要返回void类型的所有函数都有外部其他作用
M0-1-9必要不应存在无用代码
M0-1-10必要定义的函数至少应调用一次
M0-1-11必要非虚函数中不应存在未使用的参数(已命名或未命名)
M0-1-12必要用于virtual函数以及覆盖该虚函数的所有函数的参数集中不应存在未使用的参数(已命名或未命名)
存储M0-2-1必要不应将对象分配给重叠的对象
运行时错误M0-3-1文档应至少使用以下方法之一来最大程度地减少运行时故障:(a)静态分析工具/方法;(b)动态分析工具/方法;(c)显式编码检查以处理运行时错误
M0-3-2必要如果函数返回了错误信息,则应该测试该错误信息
算法M0-4-1文档应该记录使用缩放整数或定点算法的情况
M0-4-2文档应该记录使用浮点算法的情况
M0-4-3文档浮点实现应遵守定义的浮点标准
通常语言M1-0-1必要所有代码都应符合ISO/IEC14882:2003“C++标准体现技术勘误1”(The C++ Standard Incorporating Technical Corrigendum 1)
M1-0-2文档只有当编译器具有共同定义的接口时才能使用多个编译器
M1-0-3文档应该确定和记录选定编译器中整数除法的执行
固定词语字符集M2-2-1文档应该记录字符集和相应的编码
三字符序列M2-3-1必要不应使用三字符组
有向图M2-5-1建议不应使用图表
注释M2-7-1必要不应在C 风格注释中使用字符序列/*
M2-7-2必要不应使用C 风格注释将代码段“注释掉”
M2-7-3建议不应使用C++ 注释将代码段“注释掉”
标识符M2-10-1必要不同的标识符在排字上应该清楚明确
M2-10-2必要在内部范围中声明的标识符不应隐藏在外部范围中声明的标识符
M2-10-3必要typedef名称(包括属性,如果有)应是唯一的标识符
M2-10-4必要类、联合或enum名称(包括属性,如果有)必须是唯一的标识符
M2-10-5建议具有静态存储期的非成员对象或函数的标识符名称不应再次使用
进制M2-10-6必要如果标识符是指类型,则它不应该在同一个范围内也指对象或函数
M2-13-1必要只应使用在ISO/IEC 14882:2003中定义的那些转义序列
M2-13-2必要不应使用八进制常量(零除外)和八进制转义序列(“
M2-13-3必要应对所有unsigned类型的八进制或十六进制整数常量应用“U”后缀
M2-13-4必要常数值后缀应该采用大写
M2-13-5必要不应将窄字符串和宽字符串常数值连接在一起
基本概念声明和定义M3-1-1必要在不违反“一个定义规则”(One Rule)情况下可以在多个编译单元中包括任何头文件
M3-1-2必要函数不应在块范围内声明
M3-1-3必要当声明数组时,应显式指明其大小或在初始化中隐式定义其大小
一个定义规则M3-2-1必要对象或函数的所有声明都应具有兼容类型
M3-2-2必要不应违反“一个定义规则”(One Definition Rule)
M3-2-3必要在多个编译单元中使用的类型、对象或函数应在一个且仅在一个文件中声明
M3-2-4必要包含外部链接的标识符应只具有一个外部定义
陈述区域和范围M3-3-1必要不应在头文件中声明具有外部链接的对象或函数
M3-3-2必要如果函数包含内部链接,则所有重新声明应包括static存储class说明符
名字查询M3-4-1必要声明为对象或类型的标识符应在最小化其可见性的块中定义
类型M3-9-1必要用于对象、函数返回类型或函数参数的类型在所有声明和重新声明中均应为标识符相同
M3-9-2建议应该使用指示大小和符号的typedef 代替基本数值类型
M3-9-3必要不应使用浮点值的基础位表示法
标准原型完整提升M4-5-1必要不应将具有bool 类型的表达式用作内置运算符的操作数,以下运算符除外:赋值运算符=、逻辑运算符&&、||、!、等号运算符==和!=、一元&运算符以及条件运算符
M4-5-2必要不应将枚举类型的表达式用作内置运算符的操作数,以下运算符除外:下标运算符 [ ],赋值运算符 =,等号运算符 == 和 !=,一元 & 运算符以及关系运算符 <、<=、> 和 >=。
M4-5-3必要不应将具有(普通)char 和 wchar_t 类型的表达式用作内置运算符的操作数,以下运算符除外:赋值运算符 =、等号运算符 == 和 != 以及一元 & 运算符。
指针原型M4-10-1必要不应将 NULL 用作整数值。
M4-10-2必要不应将常数值零 (0) 用作非指针常量。
表达式通用M5-0-1必要在标准允许的任何求值顺序下,表达式的值都应相同
M5-0-2建议在表达式中,应有限地依赖 C++ 运算符优先规则。
M5-0-3必要不应将 cvalue 表达式隐式转换为其他基础类型
M5-0-4必要隐式整数转换不应改变基础类型的符号
M5-0-5必要不应存在隐式浮点-整数转换
M5-0-6必要隐式整数或浮点转换不应减小基础类型的长度大小
M5-0-7必要cvalue 表达式不应存在显式浮点-整数转换。
M5-0-8必要显式整数或浮点转换不应增加 cvalue 表达式基础类型的长度大小。
M5-0-9必要显式整数转换不应改变 cvalue 表达式基础类型的符号。
M5-0-10必要如果对基础类型为无符号 char 或无符号 short 的操作数应用了位运算符 ~ 和 <<,结果应立即转换为操作数的基础类型。
M5-0-11必要普通 char 类型只应该用于存储,并使用字符值。
M5-0-12必要带符号的和无符号的 char 类型只应该用于存储,并使用数字值。
M5-0-13必要if 语句的条件和迭代语句的条件都应具有 bool 类型。
M5-0-14必要条件运算符的第一个操作数应具有 bool 类型。
M5-0-15必要数组索引应该是指针算术运算唯一的形式
M5-0-16必要指针操作数以及通过针对该操作数的指针算术运算获得的指针应访问相同数组的元素
M5-0-17必要指针之间的减法运算只应该应用到访问同一数组的元素的指针
M5-0-18必要不应对类型为指针的对象应用关系运算符 >、>=、< 和 <=,除非它们指向同一数组。
M5-0-19必要对象的声明不应包含超过两级的指针间接
M5-0-20必要二进制位运算符的非常量操作数应具有相同的基础类型
M5-0-21必要位运算符只应该应用于unsigned基础类型的操作数
后置表达式M5-2-1必要逻辑 && 或 || 的每个操作数都应该是后缀表达式。?
M5-2-2必要只应通过 dynamic_cast 将虚基类的指针转换为继承类的指针。
M5-2-3建议不应对多态类型执行基class到继承class的转换
M5-2-4必要不应使用 C 风格转换(void 转换除外)和函数注解转换(显式构造函数调用除外)。
M5-2-5必要指针或引用类型的转换将不应移除任何常量或易失性属性
M5-2-6必要转换不应将函数指针转换为任何其他指针类型,包括函数类型指针
M5-2-7必要不应直接或间接将具有指针类型的对象转换为不相关的指针类型
M5-2-8必要不应将具有整数类型或 void 类型指针的对象转换为具有指针类型的对象.
M5-2-9建议转换不应将指针类型转换为整数类型
M5-2-10建议在表达式中,递增 (++) 和递减 (--) 运算符不应与其他运算符混合使用。
M5-2-11必要逗号运算符、&& 运算符和 || 运算符不应重载。
M5-2-12必要作为函数参数传递的类型为数组的标识符不应退化为指针
一元表达式M5-3-13必要! 运算符、逻辑运算符 && 或 || 的每个操作数的类型都应为 bool。
M5-3-2必要不应对基础类型为unsigned类型的表达式应用一元减运算符。
M5-3-3必要一元 & 运算符不应重载。
M5-3-4必要sizeof 运算符的操作数的评估不应包含其他作用。
左移表达式M5-8-1必要移位运算符的右操作数应介于 0 和左操作数基础类型的位宽度之间。
逻辑与操作符M5-14-1必要逻辑运算符 && 或 || 的右操作数不应包含其他作用。
指定操作符M5-17-1必要应该保留二进制运算符及其赋值运算符形式之间的语义等价
逗号操作符M5-18-1必要不应使用逗号运算符
常量操作符M5-19-1建议unsigned的整数常量表达式的求值不应导致溢出
语句表达式语句M6-2-1必要不应在子表达式中使用赋值运算符
M6-2-2必要不应直接或间接对浮点表达式执行相等或不等测试
M6-2-3必要在预处理之前,null 语句只能单独一行出现;该 null 语句可后接注释,前提是该语句后接的第一个字符是空格。
复合表达式M6-3-1必要形成 switch 主体的语句同时执行...。while 或 for 语句应是复合语句。
 M6-4-1必要if(条件)结构应该后接复合语句。else 关键字应该后接复合语句或另一个 if 语句。
选择表达式M6-4-2必要所有 if ...。else if 结构应以 else 语句结束。
M6-4-3必要switch 语句应是符合语法的 switch 语句。
M6-4-4必要switch 标签只应在最里层的复合语句是 switch 语句的主体时使用。
M6-4-5必要无条件的 throw 或 break 语句应该终止每一个非空 switch 子句。
M6-4-6必要switch 语句的最终子句应该是 default 子句。
M6-4-7必要switch 语句的条件不应包含 bool 类型。
M6-4-8必要每个 switch 语句都应该至少具有一个 case 子句。
迭代表达式M6-5-1必要for 循环应包含一个不应具有浮点类型的循环计数器。
M6-5-2必要如果循环计数器未通过 -- 或 ++ 修改,则在条件中,只应将循环计数器用作 <=、<、> 或 >= 的操作数。
M6-5-3必要不应在条件或语句中修改循环计数器
M6-5-4必要循环计数器应通过以下其中一项修改:--、++、-=n 和 +=n;其中 n 在循环持续时间内保持为常量。
M6-5-5必要除循环计数器以外的循环控制变量不应在条件或表达式内进行修改
M6-5-6必要在语句中修改的除循环计数器之外的循环控制变量应具有类型bool
跳转表达式M6-6-1必要goto 语句引用的任何标签都应在同一代码块或包括该 goto 语句的代码块中声明。
M6-6-2必要goto 语句应跳转到在同一函数后半部分中声明的标签。
M6-6-3必要不应在循环语法中使用 continue 语句。
M6-6-4必要对于任何迭代语句,用于循环终止的 break 或 goto 语句不应超过一个。
M6-6-5必要函数在函数结束处应该只有唯一的退出点
声明说明符M7-1-1必要不能修改的变量应该使用
M7-1-2必要如果函数参数是不能修改的对象,应该在函数中将相对应的参数的指针或引用声明为 const 指针或 const 引用。
枚举声明M7-2-1必要具有 enum 基础类型的表达式只应具有与枚举的枚举器对应的值。
命名空间M7-3-1必要全全局命名空间只应包含 main、命名空间声明和 extern 声明。
M7-3-2必要标识符 main 不应用于除全局函数 main 之外的函数。
M7-3-3必要头文件中不应存在未命名的命名空间
M7-3-4必要不应使用 using 指令。
M7-3-5必要同一namespace中的标识符的多个声明不应跨越该标识符的使用声明
M7-3-6必要不应在头文件中使用
asm声明M7-4-1文档应该记录所有使用汇编程序的情况
M7-4-2必要汇编程序说明只应使用 asm 声明引入。
M7-4-3必要应该独立封装汇编语言
链接规范M7-5-1必要函数不应返回在函数内定义的自动变量(包括参数)的引用或指针
M7-5-2必要在第一个对象消失后不应将自动存储对象的地址赋值给另一个可能仍然存在的对象
M7-5-3必要函数不应返回通过引用或const引用传递的参数的引用或指针
M7-5-4建议函数不应直接或间接调用自身
声明通用M8-0-1必要init-declarator-list 或 member-declarator-list 应该分别包括一个init-declarator 或 member-declarator。
声明含义M8-3-1必要覆盖virtual函数中的参数应使用与其覆盖的函数相同的默认参数,否则不应指定任何默认参数
功能定义M8-4-1必要不应使用 ellipsis 注解定义函数。
M8-4-2必要用于函数的重新声明中的参数的标识符应与声明中的标识符相同
M8-4-3必要返回非 void 类型的函数的所有退出路径都应具有包含表达式的显式返回语句。
M8-4-4必要函数标识符应该只用于函数调用,或者在其前使用 & 前缀。
初始化M8-5-1必要所有变量在使用之前都应先定义一个值
M8-5-2必要在数组和结构的非零初始化中,应使用大括号指示和匹配结构
M8-5-3必要在枚举器列表中,不应将 = 构造用于显式初始化非首位成员之外的成员,除非所有项目都已经被显式初始化。
成员方法M9-3-1必要const成员函数不应返回类数据的非常量指针或引用
M9-3-2必要成员函数不应返回类数据的非常量句柄
M9-3-3必要如果成员函数可以是static,则它应该是static,另外如果它可以是 const,则它应该是 const。
联合体M9-5-1?必要不应使用联合
位域M9-6-1?文档在需要位的绝对定位表示位域时,应该记录位域的行为和包装
M9-6-2?必要位域应该是bool类型或显式unsigned或signed的整数类型
M9-6-3?必要位域不应具有enum类型
M9-6-4?必要已命名signed整数类型的位域的长度应超过一位
子类多个基类M10-1-1建议不应该通过virtual基类来继承类
M10-1-2必要如果将基类用于菱形层次架构中,则只应将其声明为虚基类
M10-1-3必要可访问基class在同一层次架构中不能同时为virtual基类和非虚基类
成员方法查找M10-2-1建议多继承层次架构中的所有可访问实体名称都应该唯一
虚方法M10-3-1必要在整个继承层次架构中,每个virtual函数在每个路径中的定义不应超过一个
M10-3-2必要每个覆盖虚函数都应使用virtual关键字声明
M10-3-3必要如果virtual函数被声明为纯虚函数,则该virtual函数只应被纯virtual函数覆盖
成员存取控制通用M11-0-1必要非POD类类型中的成员数据应该是私有的
特殊成员方法构造器M12-1-1必要对象的动态类型不应在其构造函数或析构函数的主体中使用
M12-1-2建议class的所有构造函数都应显式调用其所有直接基类和所有virtual基类的构造函数
M12-1-3必要所有可通过单个基本类型的参数调用的构造函数都应explicit声明
拷贝类对象M12-8-1必要复制构造函数只应初始化其基类以及本类的非静态成员
M12-8-2必要复制赋值运算符在抽象class中应被声明为protected或private
模板模板声明M14-5-1必要非成员类属函数只应在不关联的namespace中声明
M14-5-2必要当存在具有一个类属参数的模板构造函数时,应声明复制构造函数
M14-5-3必要当存在具有类属参数的模板赋值运算符时,应声明复制赋值运算符
名字解析M14-6-1必要在具有从属基类的类模板中,在该从属基类中可能找到的任何名称应使用qualified-id或this->引用
M14-6-2必要由重载解析选择的函数应解析为在以前在编译单元中声明的函数
模板实例化和说明M14-7-1必要所有class模板、函数模板、class模板成员函数和class模板static成员都应至少实例化一次
M14-7-2必要对于任何指定的模板具体化,在具体化中使用模板参数的情况下,模板的显式实例化不应呈现给(传递给)不规范的程序
M14-7-3必要模板的所有部分和显式具体化应在与主模板的声明相同的文件中声明
功能模板说明M14-8-1必要不应显式具体化重载函数模板
M14-8-2建议为函数调用设置的可行函数应该不包含函数具体化,或只包含函数具体化
异常处理通用M15-0-1文档异常只应用于错误处理
M15-0-2建议异常对象不应具有指针类型
M15-0-3必要不应使用goto或switch语句将控制转化为try或catch块
抛出异常M15-1-1必要throw语句的赋值表达式本身不应导致抛出异常
M15-1-2必要不应显式抛出NULL
M15-1-3必要空throw(throw;)只应用于catch处理程序的复合语句
处理异常M15-3-1必要只应在程序启动之后并且在终止之前报告异常
M15-3-2建议至少应有一个异常处理程序用于捕获所有未处理的异常
M15-3-3必要类构造函数或析构函数的function-try-block实现的处理程序不应引用此类或其基类的非静态成员
M15-3-4必要代码中显式抛出的每个异常在所有可能导致该异常的调用路径中都应具有兼容类型的处理程序
M15-3-5必要class类型异常应始终通过引用捕获
M15-3-6必要当在针对继承类及其部分或全部基类的单个try-catch语句或function-try-block中提供多个处理程序时,应按从最上层继承类到基类的顺序排列这些处理程序
M15-3-7必要当在单个try-catch语句或function-try-block中提供多个处理程序时,所有ellipsis(catch-all)处理程序都应最后发生
例外说明M15-4-1必要如果函数使用异常规范声明,则同一函数(在其他编译单元中)的所有声明都应使用同一组类型ID来声明
特定功能M15-5-1必要class析构函数不应存在异常
M15-5-2必要当函数的声明包括异常规范时,该函数只能抛出指定类型的异常
M15-5-3必要不应隐式调用terminate()函数
预处理指令通用M16-0-1必要文件中的#include指令之前只能包含其他预处理器指令或注释
M16-0-2必要在全局namespace中,只应使用#defined #undefd定义或取消定义宏
M16-0-3必要不应使用#undef
M16-0-4必要不应定义类似于函数的宏
M16-0-5必要类似于函数的宏的参数不应包含看起来像是预处理指令的标识符
M16-0-6必要在类似于函数的宏的定义中,参数的每个实例都应使用圆括号括起,除非它被用作 # 或 ## 的操作数。
M16-0-7必要不应将未定义的宏标识符用于#if或#elif预处理器指令,除非作为定义的运算符的操作数
M16-0-8必要如果#标识符在行中显示为第一个标识符,则其后应紧接预处理标识符
条件包含M16-1-1必要定义的预处理器运算符只能采用两种标准形式中的一种
M16-1-2必要所有 #else、#elif 和 #endif 预处理器指令都应和相关的 #if 或 #ifdef 指令处在同一文件中。
源文件包含M16-2-1必要只应将预处理器用于文件包含和包含保护
M16-2-2必要C++宏只应用于包含保护、类型限定符或存储class说明符
M16-2-3必要应提供包含保护
M16-2-4必要'、"、/*或//字符不应出现在头文件名称中
M16-2-5建议\字符不应出现在头文件名称中
M16-2-6必要#include 指令应后接 <filename> 或“filename”序列。
宏取代M16-3-1必要在单个宏定义中,#或##运算符最多只应出现一次
M16-3-2建议不应使用#和##运算符
Pragma指令M16-6-1文档应该记录对#pragma指令的所有使用情况
库介绍通用M17-0-1必要不应定义、重新定义或取消定义标准库中的保留标识符、宏和函数
M17-0-2必要标准库宏和对象的名称不应再次使用
M17-0-3必要不应覆盖标准库函数的名称
M17-0-4文档All-library-code-shall-conform-to-MISRA-C++
M17-0-5必要不应使用setjmp宏和longjmp函数
语言支持库通用M18-0-1必要具有相应 C 兼容库的 C++ 库必须使用 C++ 版本。
M18-0-2必要不应使用来自库<cstdlib>中的库函数atof、atoi和atol
M18-0-3必要不应使用来自库<cstdlib>中的库函数abort、exit、getenv和system
M18-0-4必要不应使用库<ctime>的时间处理函数
M18-0-5必要不应使用库<cstring>的无边界函数
实现属性M18-2-1必要不应使用宏offsetof
动态内存管理M18-4-1必要不应使用动态堆内存分配
其它允许时支持M18-7-1必要不应使用 <csignal> 的信号处理设施。
诊断库错误数M19-3-1必要不应使用错误指示器errno
输入/输出库通用M27-0-1必要不应使用数据流输入/输出库<cstdio>

(结束)

文章来源:https://blog.csdn.net/manok/article/details/134823855
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。