MISRA C++:2023,您需要了解的下一个 MISRA 信息
发布时间:2023-10-16 15:41:24
MISRA C++ ®的背景
MISRA C++的当前版本发布于 2008 年。它为以 ISO C++ 2003 编写的安全相关软件的开发提供了专家指导。这套指南已经被广泛采用,并在许多安全关键项目中成为了强制遵循的准。然而,自那时以来,C++语言发生了相当大的变化,新的版本引入了新的语言功能,并且改变了现有的特性。
使用较新版本的 C++语言开发的项目可能不符合 MISRA C++:2008 的所有规则,并且新特性可能不在其覆盖范围之内。为了给这些新版本提供指南,AUTOSAR 以 MISRA C++:2008 为基础,结合其他标准的规则,为 C++14 制定了新的指南。MISRA C++工作组目前正在根据 AUTOSAR 指南对 MISRA C++进行更新,以适用于 C++17,但其中包括了 MISRA 已确立的安全相关 C++开发的最佳实践。
人们对新的 MISRA C++指南兴趣浓厚。然而,由于 MISRA C++:2008 已被许多项目采用,所以对于改用新的指南,人们也存在一些担忧。
MISRA C++:2023®系列文章预览
在本系列文章中,将探讨新标准的多个方面。
C++和 MISRA C++的历史
首先,文章将概述 C++编程语言的历史,从 1979 年 Bjarne Stroustrup 在贝尔实验室提出概念,到 1991 年开始标准化,再到目前的 C++20 版本。
值得注意的是,C++20 中添加的一些主要功能在之前就已经讨论过了。“模块(modules)”和“概念(concepts)”就是这种情况,它们都是新功能,为并发编程的标准化功能提供库实现(library implementations)和协程(coroutines)。直到现在,并发支持才成为指南的一部分。但在之前,这些功能已经在 Simula 编程语言中存在,与 C 语言的高效性能相结合,以提供程序组织和并发支持。
然而,必须指出,MISRA C++似乎将以 C++17 为基础。造成这种情况的原因可能是,编译器实现者需要时间来为所有语言特性提供支持,而且这些实现还需要经过认证才能用于安全关键项目。
随着时间的推移,已经有许多不同的 C++编码标准被编写出来了。不仅是前文提到的 AUTOSAR 指南,还有许多其他流行的编码标准在使用中。在今年的《汽车软件开发状况报告》中,介绍了 400 位汽车开发专业人士对于汽车软件行业当前实践和新兴趋势的问题的回答。随着电动汽车和半自动驾驶汽车的持续发展,以及随之而来的软件组件的增加,研究结果继续表明,安全性与防范性同样重要,并且是人们关注的主要问题。遵守安全标准的要求越来越高,也反映了这一点。
该报告还显示,仍然是汽车行业最流行的编码标准,42%的受访者使用 MISRA 编码标准。鉴于 MISRA 的悠久历史及其在汽车行业的深厚根基,这就不足为奇了。AUTOSAR 以 36%的比例位居第三。C++核心指南标准令人惊讶地排在第二位,占比 39%,尽管该标准与汽车行业没有明显的关系。它之所以受欢迎,可能是因为它涵盖了开发人员想要使用的最新 C++语言特性。
您目前正在使用哪些编码标准?
△《2023 年汽车软件开发状况报告》对于此问题的回应
C++编码标准的方方面面
由 Bjarne Stroustrup 和 Herb Sutter 发起的 C++核心指南是一份不断改进的动态文件。由于该标准涵盖了最新的 C++语言功能,所以也影响着 AUTOSAR 标准的制定。AUTOSAR 包括了两个标准之间的比较,显示 C++核心准则中有 30%与 AUTOSAR 规则存在冲突。MISRA C++:2023 涵盖了大部分 AUTOSAR 的问题,并且新的指南没有直接使用 C++核心准则。
Perforce 将提供一篇专门的文章,全方位比较这些 C++编码标准,包括理念、指南、执行和声明合规性。由于 MISRA C++:2023 似乎不太可能整合所有的 AUTOSAR 规则,所以 Perforce 将评估与新 MISRA C++:2023 规则中与 C++核心指南冲突的比例,并将其与 AUTOSAR 进行比较。
MISRA C++:2023 的新准则
最后,还将有一些介绍新准则的文章。
MISRA C++:2023 将提供定义类类型接口的指导规则。它提倡“规则 0(Rule of Zero)”,这意味着它更倾向于不指定特殊成员函数,因为语言标准保证了编译器已经提供了预期的实现。
这与其他建议如“规则 5”(或“规则 6”,如果您还单独计算默认构造函数的话)相矛盾,后者规定您需要始终明确指定特殊成员函数。Perforce 将讨论新规则如何处理现有指南所涵盖的漏洞。
不过,这也存在风险,从为 AUTOSAR 规则 A12-0-1 提供的合规示例中就可以看出:
class A // Compliant - the class A follow the "Rule of six" rule
{
public:
A(); // Non-default constructor
~A() = default;
A(A const&) = default;
A& operator=(A const&) = default;
A(A&&) = delete;
A& operator=(A&&) = delete;
};
复制代码
可以看到,只有移动函数(move functions)被删除了,而复制函数和析构函数被设置为默认。这样的代码可能是开发人员遵循“规则 3”到“规则 5”的代码进行扩展的结果,但开发人员试图通过删除新的移动函数来保留旧的行为。MISRA C++不允许这种特殊成员函数的组合;如果一个类提供了复制函数,那它必须同时提供移动函数。这个类的问题在于,它不能与容器一起使用。例如,当尝试声明一个该类型的向量时,由于缺少移动函数,会发生编译错误。需要注意的是,这个示例在 AUTOSAR 标准的 18-03 版本中得到了修正,规则的措辞也发生了变化,但并没有明确要求在提供复制函数时必须提供移动函数。
MISRA C++:2023 将包括限制使用标准类型转换的指南。熟悉 MISRA C:2012 的开发人员可能期望有类似的类型转换规则,就像 MISRA C 基本类型定义的规则一样,但情况并非如此。
MISRA C++:2023 要严格得多。原因是:与 C 不同,C++提供了函数重载,这取决于表达式的确切类型和自动占位符类型说明符,其中类型是从表达式派生的。如果不遵守规则,可能会出现这样的情况:包含头文件的函数重载比之前的函数重载匹配得更好,这可能是意料之外的。有一种安全的方法可以避免隐式转换,那就是使用具有整数基础类型的类型安全枚举类型。这种强类型的值不会被隐式转换。
使用 Helix QAC,确保 MISRA 合规性
Perforce 的Helix QAC是一款静态分析工具,在提供 MISRA C 和 MISRA C++合规性检查以及许多其他有价值的分析功能方面处于领先地位。
Helix QAC 提供了合规模块,用于强制执行 MISRA C 和 MISRA C++的所有版本和修订,包括 MISRA C:2023。Perforce 计划在标准发布时,提供完整的 MISRA C++:2023 合规性模块。