3

我有兴趣向覆盖检查器添加规则,并想咨询它是否可行以及需要做什么才能实现。我说的是 C 编程,我想使用定义的枚举器来限制对数组的访问——而不是任何整数索引。

例如,我有两个数组:相应orangesapples大小为 5 和 10 个单元格。

为了避免滥用数组,我想定义两个枚举(或 typedef,如果需要),一个 fororanges和一个 for apples

Enum apples {
    A0 = 0,
    A1 = 1,
    A2 = 2,
    A3 = 3,
    A4 = 4,
}

Enum oranges {
    O0 = 0,
    O1 = 1,
    O2 = 2,
    O3 = 3,
    O4 = 4,
    O5 = 5,
    O6 = 6,
    O7 = 7,
    O8 = 8,
    O9 = 9,
}

我想添加一个规则来检查对这些数组的每次访问。例如:

Apples[A4];  //success

Apples[O0]; // coverity error

Apples[2]; // coverity error

是否可以添加这样的规则?

4

3 回答 3

0

要在纯 C(而不是使用外部工具)中执行此类操作,您可以使用结构而不是枚举来表示允许的索引范围。结构是强类型的,因此类型系统将阻止您使用旨在用于一个数组的索引器来访问另一个数组。

有几种方法可以解决这个问题 - 你可以将 int 索引放在结构中,或者(假设元素范围是连续的)你可以通过直接使用结构标识而不是任何暴露的整数来使你的安全更加严格:

typedef struct { int UNUSED; } appleI;
typedef struct { int UNUSED; } orangeI;

const appleI apples[5] = { };

const orangeI oranges[10] = { };

apple_t * Apples(appleI * i) {    //The actual array is hidden from view
    static apple_t _Apples[] = { ... };
    return &_Apples[i - &apples[0]];
}

orange_t * Oranges(orangeI * i) {
    static orange_t _Oranges[] = { ... };
    return &_Oranges[i - &oranges[0]];
}

#define A0 (&apples[0])
#define A1 (&apples[1])
// ...etc

...
orange_t myOrange = ...;
*Oranges(O2) = myOrange;
apple_t myApple = *Apples(A3);
  • 您可以在“数组”函数的中间添加范围检查,以确保不使用索引类型的新实例(这肯定是一个错误 - 这些类型对用户代码应该是不透明的)

  • 你仍然可以使用A0 + 1等等

  • 对于强大的编译器来说,这些东西应该很容易内联并减少到零

于 2014-09-02T18:27:53.420 回答
0

//使用模数运算符避免越界

#include <stdio.h>
#define LIMIT 5
int main()
{

         char array[LIMIT] = {'A', 'B', 'C', 'D', 'E'};
         for(int i = 0; i < LIMIT + 3; i++)
                 printf("ELEMENT = '%c'\n", array[i%LIMIT]);

         return 0;
}
于 2014-09-02T13:19:51.797 回答
0

如果它知道长度,您可以创建一个检查这个的函数。我没有看到另一种解决方案,因为 C 没有检查出索引。

<array_type> accessArray(<array_type> array, int index, int len)
{
    if (index > len || index < 0) {
        return <error_value>; // return an error value set by you 
    } else { 
        return array[index];
    }
}
于 2014-09-02T12:01:50.600 回答