我有兴趣为覆盖性检查器添加一个规则,并且想要咨询它是否可行以及需要做些什么来实现。我在谈论C编程,我想使用定义的枚举器来限制对数组的访问 - 而不是任何整数索引。
例如,我有两个数组:oranges
和apples
,大小为5和10个单元格。
为了避免误用数组,我想定义两个枚举(或者如果需要的话是typedef),一个用于oranges
,另一个用于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
是否可以添加此规则?
如果它知道长度,你可以做一个检查这个的功能。我没有看到另一个解决方案,因为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];
}
}
//使用模块运算符避免超出限制
#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;
}
要在纯C中执行类似的操作(而不是使用外部工具),可以使用结构而不是枚举来表示允许的索引范围。结构是强类型的,因此类型系统将阻止您使用用于一个数组的索引器来访问另一个数组。
有几种方法可以解决这个问题 - 你可以将int索引放在struct中,或者(假设元素范围是连续的)你可以通过直接使用struct identities而不是任何暴露的整数来使你的安全性更加严格:
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
等