1

我有一个示例函数如下:

int get_hash (unsigned char* str)
{
    int hash = (str[3]^str[4]^str[5]) % MAX;
    int hashVal =  arr[hash];
    return hashVal;
}

这里数组 arr 的大小为 MAX。( int arr[MAX])。

我的静态代码检查器抱怨这里可能存在超出范围的数组访问,因为哈希可能在 -255 到 -1 的范围内。

它是否正确?unsigned char 的按位运算可以产生负数吗?应该将哈希声明为无符号整数吗?

4

2 回答 2

4

它是否正确?

不,静态代码检查器出错(1)

unsigned char 的按位运算可以产生负数吗?

一些按位运算可以 - 例如按位补码 - 但不能异或。

对于^unsigned char这里的参数受制于通常的算术转换(6.3.1.8),它们首先根据整数提升进行提升;关于这些,第 6.3.1.1 条第 2 段说

如果 anint可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为int; 否则,将其转换为unsigned int. 这些被称为整数促销。

所以,有两种可能:

  1. Anint可以表示 的所有可能值unsigned char。那么从整数提升中获得的所有值都是非负的,这些值的按位异或也是非负的,余数MAX也是模数。的值hash则在从 0(包括)到MAX(不包括)[ -MAXif MAX < 0] 的范围内。

  2. int不能代表 的所有可能值unsigned char。然后将值提升为 type unsigned int,并在该类型上执行按位运算。结果当然是非负的,余数模MAX也将是非负的。但是,在这种情况下,赋值int hash可能会将超出范围的值转换为负值[将超出范围的整数转换为有符号整数类型是实现定义的]。(1)但在这种情况下,可能的负值范围大于-255to -1,因此即使在这种情况下(非常不可能),静态代​​码检查器也有部分错误。

应该将 hash 声明为unsigned int?

这取决于 的值MAXMAX如果余数模数超出 的范围的可能性很小int,那么这会更安全。否则,int同样安全。

于 2013-05-28T09:23:42.977 回答
1

正如 gx_ 正确指出的那样,算术是在int. 只需再次将您的hash变量声明为unsigned char,以确保每个人都知道您希望这在所有情况下都是积极的。

如果MAX有效UCHAR_MAX,您应该使用它来提高可读性。

于 2013-05-28T09:00:19.933 回答