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

new*_*ser 1 c int bit-shift undefined-behavior unsigned-char

我有以下代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

编译时,我收到以下警告:

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)|

如何修复警告?

ric*_*ici 5

整数优惠转buf[2] << 56(int)buf[2] << 56[注1],但它是完全可能的int仅具有32位,则需要它是一个无符号的64位类型的移位是有意义的.

你期望unsigned long是64位,但可能不是.包含<stdint.h>和使用会更好uint64_t.无论如何,你需要显式地转换左移的左操作数:

((uint64_t)buf[2] << 56) | ...
Run Code Online (Sandbox Code Playgroud)

[注1]:理论上可以和a unsigned char一样宽int,在这种情况下整数提升可以是a unsigned int.但这只发生在不寻常的架构上.