繁体   English   中英

警告:左移计数> =类型的宽度[默认启用]

[英]warning: left shift count >= width of type [enabled by default]

我有以下代码:

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:警告:左移计数> =类型的宽度[默认启用] len =(buf [2] << 56)| ^ math_fun.c:241:27:警告:左移计数> =类型的宽度[默认启用](buf [3] << 48)| ^ math_fun.c:242:27:警告:左移计数> =类型的宽度[默认启用](buf [4] << 40)| ^ math_fun.c:243:27:警告:左移计数> =类型的宽度[默认启用](buf [5] << 32)|

如何解决警告?

整数提升将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 但这只会在不寻常的架构上发生。

请学习阅读警告:

math_fun.c:240:21:警告:左移计数> =类型的宽度[默认启用] len =(buf [2] << 56)| ^

这为您提供了理解错误以及如何纠正错误所需的所有信息:

移位的类型小于56位,因此移位56位或更多是未定义的行为
首先转换为更大的类型。

我希望这long适合您的平台,因为那是您稍后将结果分配给的变量的类型。 如果提供 int64_t它将保证足够大。

当你在它,可以考虑只使用unsigned类型那里,溢出signed类型是不确定的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM