文章目录

  • 前言
  • 一、准则分类
  • 二、准则级别
  • 三、准则示例
  • 四、准则解读
    • 1. 数据类型和变量声明
    • 2. 函数设计和参数传递
    • 3. 代码风格和格式
    • 4. 错误处理和异常管理
    • 5. 内存管理和指针操作
  • 总结

前言

随着汽车工业的快速发展,汽车软件的安全性和可靠性变得日益重要。MISRA C是由英国汽车工业研究协会(MISRA)制定的一套C语言编程规范,是汽车行业广泛采用的一种C语言编程标准,旨在确保C代码的安全性、可靠性以及可维护性。MISRA C主要包含三个版本,分别是MISRA C:1998、MISRA C:2004和MISRA C 2012。最新版的MISRA C 2012 AMD3(修订案3)是MISRA C 2012的一个补充和修正,新增了一些要求,也对MISRA C 2012标准中的一些要求进行了更详细的解释和说明。

一、准则分类

每个 MISRA C 2012准则都可以被归类为“规则”和“指令”。
指令是一种指导原则,无法提供执行检查合规性所需的完整描述。 为了能够执行检查,还需要其他信
息,例如可能在设计文档或要求规范中提供的信息。
规则是提供完整的要求描述的准则。 应该可以检查源代码是否符合规则而无需任何其他信息。

二、准则级别

每一条 MISRA C 准则都有一个“强制”,“必要”或“建议”属性类别。
**强制准则:**声明符合MISRA C标准的代码应符合每项强制准则,且不允许有偏离。
**必要准则:**声明符合MISRA C标准的代码应符合所有必要准则,如果有不符合项,则应有正式的偏差声明。
一份背离说明应包括:
◆ 被背离的 MISRA C 准则;
◆ 允许背离的情况:对于项目背离,它可能是一个通用的描述,如“模块 X 中的所有代码”;而对于特定背离,需要标识出背离代码发生的具体位置;
◆ 背离的理由:包括但不限于与其他可能性相比,背离的风险程度的评估。
◆ 确保安全的证明:例如,提出风险不会发生的证据,以及其所需的额外审查和测试;
◆ 背离的潜在后果以及已采取的缓解措施。
例如:

**建议准则:**仅为建议执行,应在合理可行的范围内遵循这些条目。建议准则不需要正式偏差授权,但如果不遵循正式偏离程序,则应制定替代安排以记录违规情况。

三、准则示例

每一条准则的格式如下:

例如:

四、准则解读

最新的MISRA C 2012 AMD3标准有175条准则,每条准则都有较为详细的说明和示例,这里就不再一一讲解了。下面按照分类概要介绍一些比较典型的准则。

1. 数据类型和变量声明

在MISRA C 2012中,要求使用固定宽度数据类型,如int8_t、uint8_t等。这是因为固定宽度数据类型能够提供更好的可移植性和兼容性,并且在不同的平台和编译器上具有一致的表现。此外,还规定了在特定情况下使用volatile关键字的指导原则,以确保对共享或外部变量的正确访问。

2. 函数设计和参数传递

函数是C语言程序设计的基本单元,其设计的好坏直接影响到代码的质量和可维护性。MISRA C对函数设计和参数传递提出了一些具体要求:
• 函数应具有单一职责,避免过长和过于复杂的函数。
• 函数参数应使用指针传递,以减少数据拷贝和提高效率,并强调了在使用指针传递方式时需要注意指针的有效性和安全性,以避免出现空指针解引用和内存越界等问题。
• 避免使用全局变量和静态局部变量,以减少函数间的耦合。
为了满足这些要求,开发人员在设计函数时应遵循以下原则:
• 保持函数简洁明了,每个函数只完成一个明确的任务。
• 使用指针传递大型数据结构或需要修改的参数,并对指针做好非法检查。
• 尽量减少函数间的直接依赖,通过接口或抽象层来实现模块化设计。

3. 代码风格和格式

代码风格和格式对于提高代码的可读性和可维护性至关重要。MISRA C对代码风格和格式提出了一些具体要求:
• 使用有意义的变量名和函数名,避免使用缩写和不明确的命名。
• 使用空格和缩进来提高代码的可读性,遵循一致的代码缩进规则。
• 注释应清晰明了,解释代码的意图和功能。
为了满足这些要求,开发人员在编写代码时应遵循以下实践:
• 选择描述性强且易于理解的变量名和函数名。
• 使用一致的空格和缩进规则来格式化代码。
• 在代码中需要进行解释说明的部分添加必要的注释,解释代码的工作原理和目的,要求注释应该简洁明了,能够清晰地表达代码的含义和功能。

4. 错误处理和异常管理

错误处理和异常管理是确保程序稳定性的重要手段,以确保程序在出现异常情况时能够正确地处理并避免程序崩溃或数据损坏。MISRA C对错误处理和异常管理提出了一些具体要求:
• 在函数入口处验证输入参数的有效性,避免无效输入导致的错误。
• 使用返回值或错误码来表示函数执行的结果,以便调用者进行错误处理。
• 函数执行过程中应进行异常检查和处理。
为了满足这些要求,开发人员在编写代码时应遵循以下实践:
• 在函数入口处添加参数验证逻辑,确保输入参数的有效性,尤其是对指针的检查。
• 在函数出口处返回错误码或错误信息(使用明确的返回值或错误码来表示函数执行的结果)。
• 在函数执行过程中进行异常检查和处理,在程序中加入适当的日志记录机制以方便错误排查。

5. 内存管理和指针操作

内存管理和指针操作是C语言编程中的关键部分,也是容易出错的地方。MISRA C对内存管理和指针操作提出了一些具体要求:
• 避免使用未初始化的指针,以防止野指针问题。
• 在释放内存后,将指针设置为NULL,以避免悬挂指针问题。
• 避免进行不安全的指针转换和指针算术运算。
为了满足这些要求,开发人员在编写代码时应遵循以下实践:
• 在使用指针之前,始终确保指针已被正确初始化。
• 在释放内存后,立即将指针设置为NULL。
• 使用安全的指针操作函数,如memcpy、memset等,避免直接进行指针算术运算。


总结

以上便是对MISRA C 2012标准的简介与解读,我们可以看到MISRA C标准对于提高C语言代码的安全性、可靠性和可维护性具有非常重要的作用。在实际开发中,我们应该遵守MISRA C标准的规定和要求,同时也要关注标准的发展和变化,以保持代码的健壮性和安全性。
现在有非常多的静态分析工具可以进行MISRA C标准的检查,建议大家在编码后,可以借助静态测试工具(如qac、klocwork、testbed、c++test等)进行代码扫描,以满足MISRA C标准的要求。以testbed为例,可以参考我的文章《LDRA Testbed系列(一)Testbed软件静态分析_操作指南》。