对unsigned char的按位运算

时间:2013-05-28 08:47:29

标签: c++ c bit-manipulation

我有一个示例函数如下:

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进行逐位运算产生负数吗? hash应该声明为unsigned int吗?

2 个答案:

答案 0 :(得分:4)

  

这是对的吗?

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

  

对unsigned char的按位运算是否会产生负数?

某些按位运算可以 - 例如按位补码 - 但不包括异或。

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

  

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

所以,有两种可能性:

  1. int可以代表unsigned char的所有可能值。然后,从整数提升获得的所有值都是非负的,按位异或这些值也是非负的,其余的也是模MAXhash的值在0(包括)到MAX(不包括){-MAX MAX < 0的范围内。

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

  3.   

    哈希应该声明为unsigned int吗?

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

答案 1 :(得分:1)

正如gx_正确评论的那样,算法是在int中完成的。只需将hash变量再次声明为unsigned char,以确保每个人都知道您希望在所有情况下均为正值。

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