MISRA 是否检查数组索引是否越界?

Does MISRA check if array index out of bounds?

在 MISRA-C 标准 2012 中,我找不到一条明确的规则来说明实施者需要检查是否使用索引越界访问数组。

所以可能存在超出索引/边界的数组。

也许这不是 MISRA-C 关心的,或者我错过了什么?

在 MISRA-C:2012 中有咨询规则 17.5,它要求函数的数组参数应该指定边界,以便在该函数内启用数组的越界检查。

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

规则 18.1(必需)指出任何指针运算都应产生一个指向与原始操作数相同的数组的指针。这也应该(可以说)用于涵盖越界情况,因为 arr[i] 等同于 *(arr+i) 并且您实际上不能使用数组下标 [] 运算符访问数组,只能访问一个指针(参见 )。

还有一般规则 1.3 指出程序不应包含任何形式的未定义行为,这意味着涵盖其他更具体规则未处理的所有 UB 情况。

但最终,这将是静态分析器的实现质量问题。如果可以,大多数此类工具都会执行越界检查,而不管 MISRA-C。


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

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

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

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