Skip to main content

MISRA C:2012

MISRA C:2012 是由汽车产业软件可靠性协会 (MISRA) 提出的 C 语言开发标准。MISRA C:2012 的第三版发布于 2019 年 2 月,整合了此前发布的 AMD1、TC1 的内容,包含 173 条规则。MISRA C:2012 AMD2 发布于 2020 年,增加了 2 条新的规则,支持 ISO/IEC 9899:2011。

MISRA C:2012 规则覆盖情况

NaiveSystems Analyze 支持绝大多数 MISRA C:2012 规则的静态检查,包括 AMD1 和 AMD2 的内容。注意:在 175 条规则中,有 6 条规则是不完全适用于静态检查的,包括 Dir 1.1、Dir 2.1、Dir 3.1、Dir 4.1、Dir 4.2 和 Rule 1.1。

可判定不可判定小计覆盖比例
支持总计支持总计支持总计
所有类别121121425416317593%
强制(Mandatory)5511111616100%
要求(Required)8888283211612097%
建议(Advisory)2828311313979%

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语言标准语法和约束,不得超出实现的翻译限制要求可判定
Rule 1.2不应使用语言扩展建议不可判定
Rule 1.3不得出现未定义或严重的未指定行为要求不可判定
Rule 1.4不得使用新涌现的语言特性要求可判定
未使用的代码
Rule 2.1项目不得含有不可达代码要求不可判定
Rule 2.2不得有死代码要求不可判定
Rule 2.3项目不应含有未使用的类型声明建议可判定
Rule 2.4项目不应含有未使用的标签(tag)声明建议可判定
Rule 2.5项目不应含有未使用的宏声明建议可判定
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只得使用唯一标识符定义含有外部链接的对象或函数要求可判定
Rule 5.9应该使用唯一标识符定义含有内部链接的对象或函数建议可判定
类型
Rule 6.1只得使用合适的类型来声明位域(bit-fields)要求可判定
Rule 6.2一个一位的已命名位域不得为有符号类型要求可判定
字面量和常量
Rule 7.1不得使用八进制常量要求可判定
Rule 7.2所有表示为无符号类型的整型常量都必须使用“u”或“U”后缀要求可判定
Rule 7.3小写字母“l”不得用作字面量后缀要求可判定
Rule 7.4不得将字符串字面量赋值给对象,除非对象类型为“指向const修饰的char的指针”要求可判定
声明和定义
Rule 8.1必须明确指定类型要求可判定
Rule 8.2函数类型必须为带有命名形参的原型形式要求可判定
Rule 8.3对同一对象或函数的所有声明必须使用同样的名称和类型修饰符要求可判定
Rule 8.4对含有外部链接的对象或函数进行定义时,必须有可见的兼容声明(compatible declaration)要求可判定
Rule 8.5外部对象或函数只得在一个文件里进行一次声明要求可判定
Rule 8.6含有外部链接的标识符必须有且只有一个外部定义要求可判定
Rule 8.7不应使用外部链接定义仅在一个翻译单元中被引用的函数和对象建议可判定
Rule 8.8对含有内部链接的对象和函数进行的所有声明都必须使用静态存储类说明符要求可判定
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.5sizeof运算符的操作数不得是声明为“数组类型”的函数形参强制可判定
副作用
Rule 13.1初始化器列表不得含有持续的副作用(persistent side effect)要求不可判定
Rule 13.2采用任意允许采用的求值顺序时,表达式的值和表达式的持续的副作用不得发生改变要求不可判定
Rule 13.3含有一个自增(++)或自减(--)运算符的完整表达式,除因自增或自减运算符引起的副作用外,不应含有其他潜在副作用建议可判定
Rule 13.4不得使用赋值运算符的结果建议可判定
Rule 13.5逻辑与(&&)和逻辑或(||)运算符的右操作数不得含有持续的副作用要求不可判定
Rule 13.6sizeof运算符的操作数不得包含任何有潜在副作用的表达式强制可判定
控制语句表达式
Rule 14.1循环计数器不得为基本浮点类型要求不可判定
Rule 14.2for循环必须为良构要求不可判定
Rule 14.3控制表达式不得为不变量要求不可判定
Rule 14.4if语句和迭代语句的控制表达式必须为基本布尔类型要求可判定
控制流
Rule 15.1不应使用goto语句建议可判定
Rule 15.2同一函数中,goto语句只得跳转到在其后声明的标号(label)要求可判定
Rule 15.3goto语句引用的标号(label)必须在同一代码块或上级代码块中声明要求可判定
Rule 15.4任何迭代语句最多只应使用一个break或goto语句进行终止建议可判定
Rule 15.5函数结尾应只有一个退出点建议可判定
Rule 15.6迭代语句或分支语句的主体必须为复合语句要求可判定
Rule 15.7所有if … else if构造都必须以一个else语句终止要求可判定
Switch语句
Rule 16.1所有switch语句必须为良构(well-formed)要求可判定
Rule 16.2switch标号只得出现在构成switch语句主体的复合语句的最外层要求可判定
Rule 16.3每个switch子句都必须以一个无条件break语句终止要求可判定
Rule 16.4每个switch语句都必须有default标号要求可判定
Rule 16.5在一个switch语句中,default标号必须是第一个或最后一个switch标号要求可判定
Rule 16.6每个switch语句必须至少有两个switch子句要求可判定
Rule 16.7switch表达式不得是基本布尔类型要求可判定
函数
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不得声明灵活数组成员(flexible array members)要求可判定
Rule 18.8不得使用变长数组(variable-length array)要求可判定
重叠的存储
Rule 19.1不得将对象赋值或复制给与其重叠的对象强制不可判定
Rule 19.2不应使用关键字union建议可判定
预处理指令
Rule 20.1#include指令之前只能出现只有预处理指令或注释建议可判定
Rule 20.2头文件名中不得出现字符',"或\,以及/*和//字符序列要求可判定
Rule 20.3#include指令后面必须是<filename>或"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不得用于保留标识符(reserved identifier)或保留宏名称(reserved macro name)要求可判定
Rule 21.2不得声明保留标识符(reserved identifier)和保留宏名称(reserved macro name)要求可判定
Rule 21.3不得使用<stdlib.h>中的内存分配和回收(deallocation)函数要求可判定
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>中的标准库终止函数(termination function)要求可判定
Rule 21.9不得使用<stdlib.h>中的标准库函数bsearch和qsort要求可判定
Rule 21.10不得使用标准库中的时间(time)和日期(date)函数要求可判定
Rule 21.11不得使用标准头文件<tgmath.h> 要求可判定
Rule 21.12不应使用<fenv.h>的异常处理特性建议可判定
Rule 21.13传递给<ctype.h>函数的值必须能够表示为无符号char或EOF类型强制不可判定
Rule 21.14不得使用标准库函数memcmp比较空终止字符串(null terminated string)要求不可判定
Rule 21.15指向标准库函数memcpy,memmove和memcmp的指针实参必须全部为指向兼容类型的修饰或未修饰版本的指针要求可判定
Rule 21.16标准库函数memcmp的指针实参必须指向指针类型,或者指向基本有符号类型,基本布尔类型或基本枚举类型要求可判定
Rule 21.17使用<string.h>的字符串处理函数不得产生超出指针形参引用对象边界的访问强制不可判定
Rule 21.18如果要将size_t实参传递给<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不得解引用(dereference)指向FILE对象的指针强制不可判定
Rule 22.6不得在有关文件流关闭后使用FILE指针的值强制不可判定
Rule 22.7宏EOF只得与任何能够返回EOF的标准库函数的未修改返回值比较要求不可判定
Rule 22.8在调用errno设置函数之前必须将errno值设置为零要求不可判定
Rule 22.9调用errno设置函数后必须检测errno值是否为零要求不可判定
Rule 22.10只有上一个被调用的函数是errno设置函数的情况下才能检测errno值要求不可判定