我有以下代码:
long int compute_data_length(unsigned char* buf, int data_offset) {
long int len;
if(!buf)
return -1;
switch(data_offset) {
case 2: {
len = (buf[2] << 8) | buf[3];
}
break;
case 8: {
len = (buf[2] << 56) |
(buf[3] << 48) |
(buf[4] << 40) |
(buf[5] << 32) |
(buf[6] << 24) |
(buf[7] << 16) |
(buf[8] << 8) |
(buf[9] );
}
break;
default: len = -1; break;
}
return len;
}
编译时,我收到以下警告:
math_fun.c:240:21:警告:左移计数&gt; =类型宽度[默认启用] len =(buf [2]&lt;&lt; 56)| ^ math_fun.c:241:27:警告:左移计数&gt; =类型的宽度[默认启用] (buf [3]&lt;&lt; 48)| ^ math_fun.c:242:27:警告:左移计数&gt; =类型的宽度[默认启用] (buf [4]&lt;&lt; 40)| ^ math_fun.c:243:27:警告:左移计数&gt; =类型宽度[默认启用] (buf [5]&lt;&lt; 32)|
如何修复警告?
答案 0 :(得分:5)
整数提升将buf[2] << 56
转换为(int)buf[2] << 56
[注1],但int
完全有可能只有32位,你需要它是无符号的64位类型转变是有意义的。
您希望unsigned long
为64位,但可能不是。最好包含<stdint.h>
并使用uint64_t
。无论如何,你需要显式地转换左移的左操作数:
((uint64_t)buf[2] << 56) | ...
[注1]:unsigned char
理论上可能与int
一样宽,在这种情况下,整数提升将是unsigned int
。但这只发生在不寻常的架构上。
答案 1 :(得分:0)
请学会阅读警告:
math_fun.c:240:21:警告:左移计数&gt; =类型的宽度[默认启用] len =(buf [2]&lt;&lt; 56)| ^
它为您提供了解错误所需的所有信息以及如何解决错误:
您移位的类型长度小于56位,因此移位56位或更多位是未定义的行为。
首先选择适当的大型。
我希望long
符合您平台上的帐单,因为这是您稍后将结果分配给的变量的类型。 int64_t
将保证足够大,如果提供。
当您在此时,请考虑仅使用unsigned
类型,signed
类型的溢出未定义。