MISRA C 2012 标准浅析
MISRA(The Motor Industry Software Reliability Association),汽车工业软件可靠性联会; 1994年,英国成立。致力于协助汽车厂商开发安全可靠的软件的跨国协会,其成员包括:AB汽车电子、罗孚汽车、宾利汽车、福特汽车、捷豹汽车、路虎公司、Lotus公司、MIRA公司、Ricardo公司、TRW汽车电子、利兹大学和福特VISTEON汽车系统公司。
MISRA支持C语言标准的发展历程:
MISRA C 2012目前已经修订了多次,最近版本是AMD2,已经支持C11标准。MISRA主要是功能安全,而CERT C/C++则更多的关注安全威胁。MISRA C 2012:AMD2总计规则数175条,其中规则158条,指令17条。其中指令基本上是无法被SAST工具所检测分析的。175条规则中强制为15条、必要规则120条、建议规则40条。
MISRA标准中每一条规则有很多描述信息,包括类别、可判断性、支持语言标准、分析范围、规则编号、规则描述等。请见下图示意:
对于这些规则描述项说明如下:
标准分类:规则(Rule)和指令(Directive)之间的区别:
指令是一种描述性的指导规范,它无法提供执行符合性检查所需的完整描述。为了能够进行检查,需要给评测人员提供额外的信息,如设计文件或需求说明。
指令部分主要分为:实现、编译与构建、要求追踪、代码设计四个部分,共16条规范。
规则可以对相关要求提供完整的描述,评测人员或静态分析工具可以在不需要额外信息的情况下检查源代码是否符合对应规则。
指令:仅仅依靠源代码分析,无法对指令进行合规性判定,往往需要开发人员提供更多的信息,如设计文档和要求说明。静态代码分析工具可以判断代码符合指令,但对于代码不符合指令的情况,代码分析工具给出的结果可能不一致。
规则:仅仅依靠源代码分析,就可以对规则进行判断,不需要开发人员提供更多的信息,所有的静态代码检测工具都应具有对规则进行合规性判定的能力。
Category类别:
Mandatory guidelines 强制的:2012版增加的
声明符合Misra的C代码应遵守所有强制性准则-不允许偏差
Required guidelines必须的:
公司或项目可以选择将任何必须的准则视为强制性准则,不符合需要正式的偏差许可
Advisory guidelines建议的:
建议性的,不符合应被记录,但是无需正式的偏差许可
Decidability可判定性和Undecidable 不可判定性:
Decidable可判断的,总是能够在任何程序中使用工具确定代码是否合规,否则就是不可判定的
例如:
可判定的,规则11.3:取决于源指针和目标指针的类型
不可判定的,规则12.2:取决于移位运算符右侧操作数的值。
Analysis Scope分析范围
Single translation unit rule 单一编译单元
通过隔离分析每个编译单元中的源代码,可以可靠地进行验证的代码
System rules系统级
只能通过分析整个系统中的源代码了完全检查验证
MISRA合规对于企业的价值:
- MISRA是汽车行业公认的C/C++语言编码规范;
- MISRA和AUTOSAR已经联合,即将发布C++最佳行业实践标准;
- 符合编码规范是ISO 26262:2018-6软件功能安全开发标准的内在要求之一,开发ASIL功能安全项目必须满足;
- 客户软件过程能力审核要求;
- 在研发生命周期早期发现软件中的缺陷,预防成本投入会大幅度降低投产后的售后维护成本。
对于C、C++语言开发,我们关注里面包括的运行时缺陷,例如缓冲区溢出、整数溢出、数组越界、内存泄露、空指针解引用等缺陷。但是对于出海的企业,例如车企其开发软件遵守MISRA标准是必要的。这些规则虽然大多数不会导致程序崩溃,但是会给这些软件运行带来潜在的出错风险,对于可能造成重大生命财产随时的软件还是应该去遵守的。下面我们列举几个例子、说明代码不安全性主要来源。
- 开发者编码引入的错误;
例如M6-2-1:赋值运算符不得用于子表达式; a = b = c = 10; if((x=y) != 0)
- 开发者对C/C++语言的误解;
例如:M5-0-2: 表达式中的 C++ 运算符优先规则应受到有限的依赖
x = ( a + b ); x = static_cast< uint16_t > ( a ) + b;
- 编译器不执行开发人员所期望的操作;
例如:规则 M4-5-3:类型(普通)char 和 wchar_t 的表达式不得用作除赋值运算符 =、相等运算符 == 和 ! 之外的内置运算符的操作数 = 和一元 & 运算符。
if ( ( ch >= ‘a’ ) && ( ch <= ‘z’ ) )
- 编译器包含错误;
例如: M1-0-2: (强制性,工具链,非自动化)仅当多个编译器具有通用的定义接口时,才应使用多个编译器;
如果一个模块要用C++以外的语言实现,或者使用不同的编译器编译,需确保这个模块的正确集成。强制性考虑的问题包括:堆栈使用、参数传递、数据值的存储方式(长度、对齐、混叠、叠加等)。
- 运行时错误;
例如A18-0-2: 应检查从字符串到数值的转换的错误状态:
std::uint16_t a; std::cin >> a; // 没有检测到错误
目前,业界对于MISRA C 2012:ADM2支持最好的SAST工具是Coverity,支持的规则最多,检测效果最好。其次是北大Cobot,检测效果还可以。下面是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 | 建议 | 不得有无效代码(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 语句应格式正确 | 是 | 是 | |
Rule 16.2 | 必要 | switch 标签只能出现在构成 switch 语句主体的复合语句的最外层 | 是 | 是 | ||
Rule 16.3 | 必要 | 每一个 switch 子句(switch-clause)都应以无条件 break 语句终止 | 是 | 是 | ||
Rule 16.4 | 必要 | 每个 switch 语句都应具有 default 标签 | 是 | 是 | ||
Rule 16.5 | 必要 | Default 标签应作为 switch 语句的第一个或最后一个 switch 标签 | 是 | 是 | ||
Rule 16.6 | 必要 | 每个 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>或"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 2012 标准浅析
MISRA(The Motor Industry Software Reliability Association),汽车工业软件可靠性联会; 1994年,英国成立。致力于协助汽车厂商开发安全可靠的软件的跨国协会,其成员包括:AB汽车电子、罗孚汽车、宾利汽车、福特汽车、捷…...
Redis高可用之Sentinel哨兵模式
一、背景与简介 Redis关于高可用与分布式有三个与之相关的运维部署模式。分别是主从复制master-slave模式、哨兵Sentinel模式以及集群Cluster模式。 这三者都有各自的优缺点以及所应对的场景、对应的业务使用量与公司体量。 1、主从master-slave模式 【介绍】 这种模式可以采用…...
AI “自主运行”的计算机概念正逐渐成为现实
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
数据库系统概论期末经典大题讲解(用关系代数进行查询)
今天也是结束的最为密集的考试周,在分析过程中自己也有些许解题的感悟,在此分享出来,希望能帮到大家期末取得好成绩。 一.专门的关系运算 1.选择(σ) 选择操作符用于从关系中选择满足特定条件的元组 例如,…...
算法通关村第十六关-黄金挑战滑动窗口与堆的结合
大家好我是苏麟 , 今天带来一道小题 . 滑动窗口最大值 描述 : 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 题目 : …...
基于jsp的搜索引擎
摘 要 随着互联网的不断发展和日益普及,网上的信息量在迅速地增长,在2004年4月,全球Web页面的数目已经超过40亿,中国的网页数估计也超过了3亿。 目前人们从网上获得信息的主要工具是浏览器,搜索引擎在网络中占有举足轻…...
【Altium designer 20】
Altium designer 20 1. Altium designer 201.1 原理图库1.1.1 上划岗 在字母前面加\在加字母1.1.2 自定义快捷键1.1.3 对齐1.1.4 在原有的电路图中使用封装1.1.5 利用excel创建IC类元件库1.1.6 现有原理图库分类以及调用1.1.7 现有原理图库中自动生成原理图库 1.2 绘制原理图1.…...
Proteus仿真--基于1602LCD与DS18B20设计的温度报警器
本文介绍基于1602LCD与DS18B20设计的温度报警器设计(完整仿真源文件及代码见文末链接) 仿真图如下 其中温度传感器选用DS18B20器件,主要用于获取温度数据并上传,温度显示1602LCD液晶显示器,报警模块选用蜂鸣器&#…...
Clickhouse Join
ClickHouse中的Hash Join, Parallel Hash Join, Grace Hash Join https://www.cnblogs.com/abclife/p/17579883.html https://clickhouse.com/blog/clickhouse-fully-supports-joins-full-sort-partial-merge-part3 总结 本文描述并比较了ClickHouse中基于内存哈希表的3种连接…...
Arduino驱动STS35数字温度传感器(温湿度传感器)
目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 STS35瑞士Sensirion公司新推出的温度传感器,STS35提供了一个完全校准、线性和供电电压补偿的数字输出&...
一起学docker系列之十八Docker可视化工具 Portainer:简介与安装
目录 前言1 简介2 安装过程2.1 创建docker容器数据卷2.2 构建运行protainer容器 3 Portainer 软件详细说明与界面导览3.1 查看本地Docker情况3.2 操作功能3.3 创建容器3.4 部署容器 4 Portainer的优势结语参考地址 前言 Docker作为容器化解决方案的热门工具,其可视…...
【数据结构】线段树
目录 1.概述2.代码实现2.1.聚合操作——求和2.2.聚合操作——求和、求最小值、求最大值 3.应用4.与前缀和之间的区别 更多数据结构与算法的相关知识可以查看数据结构与算法这一专栏。 1.概述 (1)线段树 (Segment Tree) 是一种二叉树形数据结构ÿ…...
王道数据结构课后代码题p175 06.已知一棵树的层次序列及每个结点的度,编写算法构造此树的孩子-兄弟链表。(c语言代码实现)
/* 此树为 A B C D E F G 孩子-兄弟链表为 A B E C F G D */ 本题代码如下 void createtree(tree* t, char a[], int degree[], int n) {// 为B数组分配内存tree* B (tree*)malloc(sizeof(tree) * n);int i 0;i…...
filter过滤器
package com.it.filter;import javax.servlet.*; import javax.servlet.annotation.WebFilter;import java.io.IOException;WebFilter(urlPatterns"/*") public class DemoFilter implements Filter {Override // 初始化的方法 只要调用一次public void init(Filte…...
MES物料的动态批次管理漫谈
在制造企业中,原辅材料占产品制造总成本基本在60%以上,特殊材料加工企业可能达到80%以上,按“2/8管理原则”管理好物料就基本做好制造企业的成本管理,这也许是很多企业向“数字化转型”的一个主要原因,希望借助数字信息…...
【爬虫逆向分析实战】某笔登录算法分析——本地替换分析法
前言 作者最近在做一个收集粉币的项目,可以用来干嘛这里就不展开了😁,需要进行登录换算token从而达到监控收集的作用,手机抓包发现他是通过APP进行计算之后再请求接口的,通过官网分析可能要比APP逆向方便多࿰…...
vue3使用动态component
使用场景: 多个组件通过component标签挂载在同一个组件中,通过触发时间进行动态切换。vue3与vue2用法不一样,这里有坑! 使用方法: 1.通过vue的defineAsyncComponent实现挂载组件 2.component中的is属性 父组件&am…...
单机游戏推荐:巨击大乱斗 GIGABASH 中文安装版
在泰坦之中称霸天下吧!《GigaBash 巨击大乱斗》是一款多人战斗擂台游戏,有着受特摄片启发的巨型怪兽,具有传奇色彩的英雄,震天动地的特别攻击,以及可以完全摧毁的擂台场景。 游戏特点 怪物大解放 多达10个独特的角…...
计算机系统启动过程
计算机系统启动过程 阅读笔记: 《计算机体系结构基础(第三版)》-- 胡伟武 第7章:计算机系统启动过程分析 系统启动的整个过程中, 计算机系统在软件的控制下由无序到有序, 所有的组成部分都由程序管理, 按照程序的执行发挥各自的功…...
DedeCms后台文章列表文档id吗?或者快速定位id编辑文章
我们在建站时有的时候发现之前的文章有错误了,要进行修改,但又不知道文章名,只知道大概的文章id,那么可以搜索到DedeCms后台文章列表文档id吗?或者快速定位文章id方便修改? 第一种方法:复制下面…...
【开发问题解决方法记录】03.dian
登录提示 ERR-1002 在应用程序 "304" 中未找到项 "ROLE_ID" 的项 ID。 一开始找错方向了,以为是代码错误,但是后来在蒋老师的提醒下在共享组件-应用程序项 中发现设的项不是ROLE_ID而是ROLEID,怪不得找不到ORZ 解决方法…...
QT之QString
QT之QString 添加容器 点击栅格布局 添加容器,进行栅格布局 布局总结:每一个模块放在一个Group中,排放完之后,进行栅格布局。多个Group进行并排时,先将各个模块进行栅格布局,然后都选中进行垂直布…...
常见的几种计算机编码格式
前言: 计算机编码是指将字符、数字和符号等信息转换为计算机可识别的二进制数的过程,正因如此,计算机才能识别中英文等各类字符。计算机中有多种编码格式用于表示和存储文本、字符和数据,实际走到最后都是二进制,本质一…...
3D旋转tab图
上图 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>3D旋转tab图</title><style>* {margin: 0;padding: 0;}body {height: 100vh;background: linear-gradient(to top, #29323c, #…...
openGL 三:矩阵和向量
1.使用glm数学库进行矩阵和向量的计算 2.位置坐标可以看做一个向量 3.向量的移动,缩放,旋转,都是可以通过和矩阵的计算得出 4.向量的缩放乘一个44的矩阵 5.注意事项(有些版本的glm::mat4 不是默认构建一个单位44的矩阵)…...
Socket和Http的通讯原理,遇到攻击会受到哪些影响以及如何解决攻击问题。
德迅云安全-领先云安全服务与解决方案提供商 Socket和HTTP通信原理: Socket通信原理: Socket是一种应用程序编程接口(API),用于在单个进程或多个进程之间进行通信。它提供了一种灵活的、异步的通信方式,使…...
【springboot】整合redis
1.前提条件:docker安装好了redis确定redis可以访问 可选软件: 2.测试代码 (1)redis依赖 org.springframework.boot spring-boot-starter-data-redis (2)配置redis (3) 注入 Resource StringRedisTemplate stringRedisTemplate; 对键进行操作 –o…...
回溯和分支算法
状态空间图 “图”——状态空间图 例子:农夫过河问题——“图”状态操作例子:n后问题、0-1背包问题、货郎问题(TSP) 用向量表示解,“图”由解向量扩张得到的解空间树。 ——三种图:n叉树、子集树、排序树 剪枝 不满住条件的…...
深入理解:指针变量的解引用 与 加法运算
前言 指针变量的解引用和加法运算是非常高频的考点,也是难点,因为对初学者的不友好,这就导致了各大考试都很喜欢在这里出题,通常会伴随着强制类型转换、二维数组、数组指针等一起考查大家对指针的理解。但是不要怕,也许…...
Docker 镜像构建的最佳做法
一、镜像分层 使用docker image history命令,可以看到用于在镜像中创建每个层的命令。 1、 使用docker image history命令查看创建的入门镜像中的层。 docker image history getting-started 您应该得到如下所示的输出: IMAGE CREATED…...
全国电子网站建设/今日头条最新新闻消息
从 1 到完美,用 js 和 react-native 写一个 APP facebook 在 2013 年开源了 react 后,紧接着在 2015 年就又开源了 react-native,就此打开了用 js 和前端技术写原生 android&ios APP 之路。尽管到目前为止 react-native 最新版本是 0.56.…...
wordpress 文章索引/无锡seo公司
这是一个允许您流式传输子流程输出的解决方案。事后使用相同的模板静态加载它(假设您的子进程将其自己的输出记录到文件中;如果没有,则将进程输出记录到日志文件中留给读者练习)from flask import Response, escapefrom yourapp import appfrom subprocess import P…...
电商设计网站有哪些功能模块/今日头条(官方版本)
环境: vs2013 windows10 parallel desktop macos big sur 项目: .net framework 2.0 4.0串儿, dll web 串 起因: 从工作室电脑上 也是pd下的win系统 装了 iis的 创建的这么个网站解决方案,然后引用了里面的dll的分项目 回家来编辑的时候, win10里面装了iis以后,启动…...
建站工具交流/宁波seo公司推荐
先筛出来1000以内的素数。枚举x^(1/3) 和 y^(1/3)以内的素因子,这样除完以后对于x和y剩下的因子,小的那个的平方必须等于大的。然后判断每个素因数的次数之和是否为3的倍数,并且小的那个次数不小于大的次数的两倍。当然这题是有O(…...
网站建设 时间安排/seo是什么平台
需求 对于部署在阿里云上的重要系统一般是不让其他人访问的,所以会在负载均衡(SLB)上加上访问控制列表。而使用ASDL拨号上网的宽带来说一般公网IP都不会固定的,会随时变更公网IP,所以此脚本正是解决此需求。 说明 脚本运行前需要先安装aliyun…...
电子商务网站开发需要注意问题/百度收录提交
****文件操作命令**** ls #以默认方式显示文件列表 -a 显示所有文件 -l 显示文件属性 -lt 按照修改时间进行排序cd #切换路径 / 根目录 .. 上一级目录 ../.. 上二级目录 ~ 切换到用户目录cp #拷贝文件 cp /root/source 将root目录下的source文件复制到当前目录 cp source targe…...