【MISRA-C-2012】:标准的理解与学习

一、前言

parasoftchina
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、引用

其他博文
1、MISRA C 2012 标准浅析
2、MISRA C 2012标准学习与理解
3、LDRA Testbed软件静态分析_操作指南

三、MISRA C 2012规则全集

下面是MISRA C 2012规则全集

子类编号类别规则项支持启用
子类编号类别规则项支持启用
指令实施/实现Dir 1.1必要程序输出所依赖的任何由实现定义的行为都应被记录和理解
指令编译与构建Dir 2.1必要所有源文件都应通过编译且没有任何编译错误
指令需求可追溯性Dir 3.1必要所有代码应可追溯到书面要求
指令代码设计Dir 4.1必要所有运行时缺陷都最小化
指令代码设计Dir 4.2建议汇编语言的所有运用都应记录在案
指令代码设计Dir 4.3必要汇编语言应被封装和隔离
指令代码设计Dir 4.4建议代码段不应被“注释掉”
指令代码设计Dir 4.5建议具有相同可见性的相同名称空间中的标识符在印刷/屏幕显示上应明确
指令代码设计Dir 4.6建议应使用指示大小和符号的 typedef 类型代替基本数字类型
指令代码设计Dir 4.7必要如果函数返回错误信息,则应测试该错误信息
指令代码设计Dir 4.8建议如果一个指向结构体或联合体的指针在编译/解释时从未被反引用,则应隐藏该对象的实现
指令代码设计Dir 4.9建议应该优先使用函数,而不是类似函数的宏(如果它们可以互换)
指令代码设计Dir 4.10必要应采取预防措施以防止头文件的内容被多次包含
指令代码设计Dir 4.11必要应该检查传递给库函数的值的有效性。
指令代码设计Dir 4.12必要不得使用动态内存分配
指令代码设计Dir 4.13建议用于对资源进行操作的功能应按适当的顺序调用
指令代码设计Dir 4.14必要应该检查从外部源接收的值的有效性。
规则标准 C 环境Rule 1.1必要程序不得违反标准 C 语法和约束,并且不得超出具体实现的编译限制
规则标准 C 环境Rule 1.2建议不应该使用语言扩展
规则标准 C 环境Rule 1.3必要不得发生未定义或严重的未指定行为
规则标准 C 环境Rule 1.4必要不得使用不成熟的语言特性
规则未使用的代码Rule 2.1必要项目不能包含不可达代码
规则未使用的代码Rule 2.2建议不得有无效代码(dead code)
规则未使用的代码Rule 2.3建议项目不应包含未被使用的类型(type)声明
规则未使用的代码Rule 2.4建议项目不应包含未被使用的类型标签(tag)声明
规则未使用的代码Rule 2.5建议项目不应包含未被使用的宏(macro)声明
规则未使用的代码Rule 2.6建议函数不应包含未被使用的执行标签(label)声明
规则未使用的代码Rule 2.7建议函数中不应有未使用的变量
规则注释Rule 3.1必要字符序列注释“/*”和“//”(/*与//)不应出现在注释中
规则注释Rule 3.2必要“//”注释中不得使用换行(即“//”注释中不得使用行拼接符“\”)
规则字符集和词汇约定Rule 4.1必要八进制和十六进制转译序列应有明确的终止识别标识
规则字符集和词汇约定Rule 4.2建议禁止使用三字母词(trigraphs)
规则标识符Rule 5.1必要外部标识符不得重名
规则标识符Rule 5.2必要同范围和命名空间内的标识符不得重名
规则标识符Rule 5.3必要内部声明的标识符不得隐藏外部声明的标识符
规则标识符Rule 5.4必要宏标识符不得重名
规则标识符Rule 5.5必要宏标识符与其他标识符不得重名
规则标识符Rule 5.6必要typedef 名称应是唯一标识符
规则标识符Rule 5.7必要标签(tag)名称应是唯一标识符
规则标识符Rule 5.8必要全局(external linkage)对象和函数的标识符应是唯一的
规则标识符Rule 5.9建议局部全局(internal linkage)对象和函数的标识符应是唯一的
规则类型Rule 6.1必要位域(位带)仅允许使用适当的类型来声明(位域成员类型限制)
规则类型Rule 6.2必要单比特(single-bit)位域成员不可声明为有符号类型
规则字符和常量Rule 7.1必要禁止使用八进制常数
规则字符和常量Rule 7.2必要后缀“u”或“U”应使用于所有无符号的整数常量
规则字符和常量Rule 7.3必要小写字符“l”不得作为常量的后缀使用(仅可使用“L”)
规则字符和常量Rule 7.4必要除非对象的类型为“指向 const char 的指针”,否则不得将字符串常量赋值给该对象
规则声明和定义Rule 8.1必要类型须明确声明
规则声明和定义Rule 8.2必要函数类型应为带有命名形参的原型形式
规则声明和定义Rule 8.3必要对象或函数的所有声明均应使用相同的名称和类型限定符
规则声明和定义Rule 8.4必要全局(external linkage)的对象和函数,应有显式的合规的声明
规则声明和定义Rule 8.5必要全局对象或函数应在且只在一个文件中声明一次
规则声明和定义Rule 8.6必要全局标识符应在且只在一处定义
规则声明和定义Rule 8.7建议仅在本编译单元中调用的对象和函数,应定义成局部属性
规则声明和定义Rule 8.8必要“static”修饰符应用在所有局部全局对象和局部函数(internal linkage)的声明中
规则声明和定义Rule 8.9建议若一个对象的标识符仅在一个函数中出现,则应将它定义在块范围内
规则声明和定义Rule 8.10必要内联函数应使用静态存储类声明
规则声明和定义Rule 8.11建议声明具有外部链接的数组时,应明确指定其大小
规则声明和定义Rule 8.12必要在枚举列表中,隐式指定的枚举常量的值应唯一
规则声明和定义Rule 8.13建议指针应尽可能指向 const 限定类型
规则声明和定义Rule 8.14必要不得使用类型限定符“restrict”
规则初始化Rule 9.1强制具有自动存储持续时间的对象(临时变量)的值在设置前不得读取
规则初始化Rule 9.2必要集合或联合体的初始化应括在花括号“{}”中
规则初始化Rule 9.3必要数组不得部分初始化
规则初始化Rule 9.4必要数组的元素不得被初始化超过一次
规则初始化Rule 9.5必要在使用指定初始化方式初始化数组对象的情况下,应明确指定数组的大小
规则基本类型模型Rule 10.1必要操作数不得为不适当的基本类型
规则基本类型模型Rule 10.2必要字符类型的表达式不得在加减运算中使用不当
规则基本类型模型Rule 10.3必要表达式的值不得赋值给具有较窄基本类型或不同基本类型的对象
规则基本类型模型Rule 10.4必要执行常规算术转换的运算符的两个操作数应有相同的基本类型
规则基本类型模型Rule 10.5建议表达式的值不应(强制)转换为不适当的基本类型
规则基本类型模型Rule 10.6必要复合表达式的值不得赋值给具有较宽基本类型的对象
规则基本类型模型Rule 10.7必要如果将复合表达式用作执行常规算术转换的运算符的一个操作数,则另一个操作数不得具有更宽的基本类型
规则基本类型模型Rule 10.8必要复合表达式的值不得转换为其他基本类型或更宽的基本类型
规则指针类型转换Rule 11.1必要不得在指向函数的指针和任何其他类型的指针之间进行转换
规则指针类型转换Rule 11.2必要不得在指向不完整类型的指针和其他任何类型间进行转换
规则指针类型转换Rule 11.3必要不得在指向不同对象类型的指针之间执行强制转换
规则指针类型转换Rule 11.4建议不得在指向对象的指针和整数类型之间进行转换
规则指针类型转换Rule 11.5建议不得将指向 void 的指针转换为指向对象的指针
规则指针类型转换Rule 11.6必要不得在指向 void 的指针和算术类型之间执行强制转换
规则指针类型转换Rule 11.7必要不得在指向对象的指针和非整数算术类型之间执行强制转换
规则指针类型转换Rule 11.8必要强制转换不得从指针指向的类型中删除任何 const 或 volatile 限定符
规则指针类型转换Rule 11.9必要宏“NULL”是整数型空指针常量的唯一允许形式
规则表达式Rule 12.1建议表达式中运算符的优先级应明确
规则表达式Rule 12.2必要移位运算符的右操作数应在零到比左操作数基本类型的位宽度小一的范围内
规则表达式Rule 12.3建议不得使用逗号(,)运算符
规则表达式Rule 12.4建议常量表达式的求值不应导致无符号整数的回绕
规则表达式Rule 12.5建议sizeof运算符不能有声明为“类型数组”的函数参数作为操作数
规则副作用Rule 13.1必要初始化程序列表不得包含持久性副作用
规则副作用Rule 13.2必要在所有允许的评估顺序中表达式的值及其持久的其他作用应该保持相同。
规则副作用Rule 13.3建议包含自增(++)或自减(–)运算符的完整表达式,除由自增或自减运算符引起的副作用外,不应有其他潜在的副作用
规则副作用Rule 13.4建议不得使用赋值运算符的结果
规则副作用Rule 13.5必要逻辑与(&&)和逻辑或(||)的右操作数不得含有持久性副作用
规则副作用Rule 13.6强制sizeof 运算符的操作数不得包含任何可能产生副作用的表达
规则控制语句表达式Rule 14.1必要循环计数器的基本类型不能为浮点型
规则控制语句表达式Rule 14.2必要for 循环应为良好格式
规则控制语句表达式Rule 14.3必要控制表达式不得是值不变的
规则控制语句表达式Rule 14.4必要if 语句和循环语句的控制表达式的基本类型应为布尔型
规则控制流Rule 15.1建议不应使用 goto 语句
规则控制流Rule 15.2必要goto 语句仅允许跳到在同一函数中声明的稍后位置的标签
规则控制流Rule 15.3必要goto语句引用的标签必须在goto语句所在代码块或包含该代码块的上级代码块中声明
规则控制流Rule 15.4建议最多只能有一个用于终止循环语句的 break 或 goto 语句
规则控制流Rule 15.5建议应仅在函数的末尾有单个函数出口
规则控制流Rule 15.6必要循环语句和选择语句的主体应为复合语句
规则控制流Rule 15.7必要所有的 if…else if 构造都应以 else 语句结束
规则Switch 语句Rule 16.1必要switch 语句应格式正确
规则Switch 语句Rule 16.2必要switch 标签只能出现在构成 switch 语句主体的复合语句的最外层
规则Switch 语句Rule 16.3必要每一个 switch 子句(switch-clause)都应以无条件 break 语句终止
规则Switch 语句Rule 16.4必要每个 switch 语句都应具有 default 标签
规则Switch 语句Rule 16.5必要Default 标签应作为 switch 语句的第一个或最后一个 switch 标签
规则Switch 语句Rule 16.6必要每个 switch 语句应至少有两个 switch 子句
规则Switch 语句Rule 16.7必要switch 语句的控制表达式(switch-expression)的基本类型不得是布尔型
规则函数Rule 17.1必要不得使用<stdarg.h>的功能
规则函数Rule 17.2必要函数不得直接或间接调用自身(不得使用递归函数)
规则函数Rule 17.3强制禁止隐式声明函数
规则函数Rule 17.4强制具有非 void 返回类型的函数的所有退出路径都应为具有带有表达式的显式return 语句
规则函数Rule 17.5建议与数组型函数形参对应的函数入参应具有适当数量的元素
规则函数Rule 17.6强制数组形参的声明不得在[]之间包含 static 关键字
规则函数Rule 17.7必要非 void 返回类型的函数的返回值应该被使用
规则函数Rule 17.8建议不应更改函数形参
规则指针和数组Rule 18.1必要指针操作数的算术运算应仅用于寻址与该指针操作数相同数组的元素
规则指针和数组Rule 18.2必要指针之间的减法应仅用于寻址同一数组元素的指针
规则指针和数组Rule 18.3必要关系运算符>,> =,<和<=不得应用于指针类型的对象,除非它们指向同一对象
规则指针和数组Rule 18.4建议“+,-,+=”和“-=”运算符不得应用于指针类型的表达式
规则指针和数组Rule 18.5建议声明中最多包含两层指针嵌套
规则指针和数组Rule 18.6必要具有自动存储功能的对象的地址不得复制给在它的生命周期结束后仍会存在的另一个对象
规则指针和数组Rule 18.7必要不得声明可变的数组成员
规则指针和数组Rule 18.8必要不得使用可变长数组类型
规则重叠存储Rule 19.1强制不得将对象赋值或复制给重叠的对象
规则重叠存储Rule 19.2必要不得使用 union 关键字
规则预处理指令Rule 20.1建议#include 指令之前仅允许出现预处理指令或注释
规则预处理指令Rule 20.2必要头文件名中不得出现“'”、“"”、“\”、字符以及“/*”或“//”字符序列
规则预处理指令Rule 20.3必要#include 指令后须跟随或"filename"序列
规则预处理指令Rule 20.4必要宏不得与关键字同名
规则预处理指令Rule 20.5建议不应使用#undef
规则预处理指令Rule 20.6必要看起来像预处理指令的符号不得出现在宏参数内
规则预处理指令Rule 20.7必要宏参数展开产生的表达式应放在括号内
规则预处理指令Rule 20.8必要#if 或#elif 预处理指令的控制表达式的计算结果应为 0 或 1
规则预处理指令Rule 20.9必要#if 或#elif 预处理指令的控制表达式中使用的所有标识符应在其评估前被#define 定义
规则预处理指令Rule 20.10建议不应使用“#”和“##”预处理运算符
规则预处理指令Rule 20.11必要紧跟在“#”运算符之后的宏参数后面不得紧随“##”运算符
规则预处理指令Rule 20.12必要用作“#”或“##”运算符的操作数的宏参数,不得是本身需要进一步宏替换的操作数
规则预处理指令Rule 20.13必要以“#”作为第一个字符的一行代码应为有效的预处理指令
规则预处理指令Rule 20.14必要所有#else,#elif 和#endif 预处理程序指令都应和与其相关的#if,#ifdef 或#ifndef 指令位于同一文件中
规则标准库Rule 21.1必要不得将#define 和#undef 用于保留的标识符或保留的宏名称
规则标准库Rule 21.2必要不得声明保留的标识符或宏名称
规则标准库Rule 21.3必要不得使用<stdlib.h>中的内存分配和释放函数
规则标准库Rule 21.4必要不得使用标准头文件<setjmp.h>
规则标准库Rule 21.5必要不得使用标准头文件<signal.h>
规则标准库Rule 21.6必要不得使用标准库输入/输出函数
规则标准库Rule 21.7必要不得使用<stdlib.h>中的 atof、atoi、atol 和 atoll 函数
规则标准库Rule 21.8必要不得使用<stdlib.h>中的 abort, exit, getenv 和 system 函数
规则标准库Rule 21.9必要不得使用<stdlib.h>中的 bsearch 和 qsort 函数
规则标准库Rule 21.10必要不得使用标准库时间和日期功能
规则标准库Rule 21.11必要不得使用标准头文件<tgmath.h>
规则标准库Rule 21.12建议不得使用<fenv.h>的异常处理功能
规则标准库Rule 21.13强制在 <ctype.h> 中传递给函数的任何值都应表示为 unsigned char或者值 EOF。
规则标准库Rule 21.14必要不应使用标准库函数 memcmp 与以 null 终止的字符串进行比 较。
规则标准库Rule 21.15必要标准库函数 memcpy、memmove 和 memcmp 的指针参数应该是指向兼容类型的合格或不合格版本的指针。
规则标准库Rule 21.16必要标准库函数 memcmp 的指针参数应该指向指针类型、本质上signed 类型、本质上 unsigned 类型、本质上 Boolean 类型或者本质上 enum类型。
规则标准库Rule 21.17强制使用来自 <string.h> 中的字符串处理函数不应导致访问超出它们的指针参数引用的对象的范围。
规则标准库Rule 21.18强制传递给 <string.h> 中的任何函数的 size_t 参数都应有一个适当的值。
规则标准库Rule 21.19强制只应将标准库函数 localeconv、getenv、setlocale 或 strerror返回的指针用作它们好像具有指向 const 限定类型的指针。
规则标准库Rule 21.20强制标准库函数 asctime、ctime、gmtime、localtime、localeconv、getenv、setlocale 或 strerror 返回的指针不应后接调用相同函数的后续调用。
规则标准库Rule 21.21必要不应使用 <stdlib.h> 的标准库函数 system。
规则资源Rule 22.1必要通过标准库功能动态获取的所有资源均应明确释放
规则资源Rule 22.2强制只有通过标准库函数分配的内存块才能释放
规则资源Rule 22.3必要不得在不同的数据流上同时打开同一文件以进行读写访问
规则资源Rule 22.4强制禁止尝试对以只读方式打开的流执行写操作
规则资源Rule 22.5强制禁止反引用指向 FILE 对象的指针
规则资源Rule 22.6强制关联的流关闭后,禁止再使用指向 FILE 的指针值
规则资源Rule 22.7必要宏 EOF 只应与能够返回 EOF 的任何标准库函数的未修改返回值进行比较。
规则资源Rule 22.8必要在调用 errno-setting-function 之前,应将 errno 的值设置为零。
规则资源Rule 22.9必要在调用 errno-setting-function 之后,应测试 errno 的值是否为零。
规则资源Rule 22.10必要仅当要调用的最后一个函数为 errno-setting-function 时,才应测试 errno 的值。

四、Misra-C 规则详解

Misra-C全解读 - Rule 1 标准的C语言环境(待更新)

Misra-C全解读 - Rule 2 未使用的代码(待更新)

Misra-C全解读 - Rule 3 注释

Rule 3.1 【必要】字符序列注释符号“/*”和“//”(/*与//)不应出现在注释的内容中

LDRA Standards for C / C++解释
在这里插入图片描述

Rule 3.2 【必要】“//”注释中不得使用换行(即“//”注释中不得使用行拼接符“\”)

行注释不能出现拼接符

LDRA Standards for C / C++解释
在这里插入图片描述

Misra-C全解读 - Rule 4 字符与语法规定(待更新)

Misra-C全解读 - Rule 5 标准的C语言环境(更新中…)

Rule5.6 【必要】typedef 名称应是唯一标识符

LDRA Standards for C / C++解释在这里插入图片描述
Misra2012解释
在这里插入图片描述

Misra-C全解读 - Rule 6 未使用的代码(待更新)

Misra-C全解读 - Rule 7 字符和常量(待更新)

Misra-C全解读 - Rule 8 声明和定义(待更新)

Misra-C全解读 - Rule 9 初始化(待更新)

Rulde 9.2 【必要】集合或联合体的初始化应括在花括号“{}”中

Misra2012解释
在这里插入图片描述
Rulde 9.3 【必要】 数组不得部分初始化
Misra2012解释
在这里插入图片描述

Misra-C全解读 - Rule 10 基础类型(更新中…)

Rule 10.1 【必要】对有符号数进行位运算 是不安全的,符号可能丢失
只能对无符号数进行位运算

LDRA Standards for C / C++解释在这里插入图片描述
举例:
在这里插入图片描述
解决方法:数据后面添加u
0xFF改成0x00FFu

Rule10.5 【必要】 表达式的值不应(强制)转换为不适当的基本类型
比如char类型值不能给bool, enum, float

Misra2012解释
在这里插入图片描述

Misra-C全解读 - Rule 11 指针类型转换(待更新)

Misra-C全解读 - Rule 12 表达式(待更新)

Misra-C全解读 - Rule 13 副作用(待更新)

Misra-C全解读 - Rule 14 控制表达式(待更新)

Misra-C全解读 - Rule 15 控制流(更新中…)

Rule 15.6 【必要】 循环语句和选择语句的主体应为复合语句
循环语句:while, do…while, for
选择语句:if else witch
需要采用复合语句写法,也就是需要花括号{}

Misra2012解释
在这里插入图片描述

Rule 15.7 【必要 】所有的 if…else if 构造都应以 else 语句结束

LDRA Standards for C / C++解释在这里插入图片描述
Misra2012解释在这里插入图片描述

Misra-C全解读 - Rule 16 Switch语句(待更新)

Misra-C全解读 - Rule 17 函数(更新中…)

Rule 17.7 【必要】 非 void 返回类型的函数的返回值应该被使用

LDRA Standards for C / C++解释在这里插入图片描述
Misra2012解释
在这里插入图片描述

Misra-C全解读 - Rule 18 指针和数组(更新中…)

R.18.1 【必要】数组越界风险

LDRA Standards for C / C++解释在这里插入图片描述
实际代码
在这里插入图片描述
可以改成
在这里插入图片描述

Misra-C全解读 - Rule 19 交叉存储(待更新)
Misra-C全解读 - Rule 20 预处理指令(待更新)
Misra-C全解读 - Rule 21 标准库(待更新)
Misra-C全解读 - Rule 22 资源(待更新)

五、工具LDRA

其他博文
1、LDRA Testbed软件静态分析_操作指南

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MISRA-C-2012是一种针对C编程语言的软件开发规范,旨在帮助开发人员编写高质量、安全、可靠的嵌入式系统软件。该规范由MISRA(Motor Industry Software Reliability Association)组织制定,是一份非常严格和规范的标准,包含了大量的编码规则和指南,旨在避免C语言程序中常见的错误和潜在的安全问题。 MISRA-C-2012规范对于内存管理、控制语句、表达式、数据类型、函数等方面都有详细的规则和建议,例如在使用指针时需要遵守的规则、如何使用控制语句、如何定义函数原型等内容。除此之外,该规范还对编码风格、变量名命名规范等方面进行了规定,以便使程序代码更易于理解和维护。 遵守MISRA-C-2012规范的好处是显而易见的,首先可以增加代码的可读性和可维护性,提高程序的质量和稳定性。其次,通过规范化的编码规则,可以有效地减少程序中的bug和错误,提高软件的可靠性和安全性。另外,MISRA-C-2012规范还有助于提高软件开发人员的编码水平和技术素养,促进团队之间的协作和沟通。 总的来说,MISRA-C-2012规范对于开发嵌入式系统软件的团队和个人来说是一份非常有价值的参考文档,它能够帮助开发人员编写出更加可靠和高质量的软件,符合行业标准和市场需求。因此,我们应该在软件开发过程中严格遵守MISRA-C-2012规范,以确保软件的质量和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Autosar️研究员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值