MISRA是否检查数组索引是否超出范围?

问题描述

在MISRA-C标准2012中,我找不到明确的规则,说实施者需要检查数组是否未使用超出范围的索引进行访问。

因此可能存在索引/边界之外的数组。

也许这不是MISRA-C关心的东西,还是我错过了什么?

解决方法

在MISRA-C:2012中,有一条咨询规则17.5,该规则要求函数的数组参数应指定范围,以允许对该函数内部的数组进行越界检查。

在早期的MISRA-C中,有一条规则赞成对函数参数使用数组语法表示法(int [])而不是指针表示法(int*),但是由于所有数组的存在,它存在一些误导无论如何,参数都会被调整(“衰减”)为指向第一个元素的指针,因此,除非指定了边界,否则数组语法本身不会添加任何内容。该规则被重写为当前的咨询规则17.5。

规则18.1(必需)指出,任何指针算术都应导致指针指向与原始操作数相同的数组。 (可以说)这也应该用来覆盖超出范围的情况,因为arr[i]等效于*(arr+i),并且您实际上不能使用数组下标[]运算符来访问数组,只能使用指针(请参阅Do pointers support "array style indexing"?)。

还有一条通用规则1.3规定,程序不应包含任何形式的未定义行为,这旨在涵盖所有其他更具体规则未处理的UB情况。

但是最后,对于静态分析器而言,这将是实现质量的问题。只要有能力,无论MISRA-C如何,大多数这样的工具无论如何都会执行越界检查。


不幸的是,在VLA方面,MISRA-C与C11委员会遭受着同样的误导思想-C11使VLA成为可选项,而MISRA-C则完全禁止了它们。两个委员会都没有考虑到现代C编程,您可以在其中使用 VLA指针来增加类型安全性和静态分析的可能性,即:

void func (size_t n,int arr[n])

这告诉静态分析器它可以检查arr内部对func的访问是否超过n。 Wheras (size_t n,int* arr)不会告诉堆栈分析器插孔。

MISRA-C:2012禁止使用这种防御性编程方法来创建更好的静态分析和更安全的程序,C11 / C17使其成为可选方法。虽然分配的VLA对象很有用,但指向VLA的指针在现代C编程中非常有用。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...