bitshifting unsigned char和unsigned long long错误

时间:2016-10-13 21:54:24

标签: c++ visual-c++ visual-studio-2015 x86-64

这是我(想要)用于解码无符号char []缓冲区中的数字以进行网络化的函数。

inline unsigned long long getULongLongLongInt(const unsigned char* buffer)
{
    unsigned long long number= (buffer[0] << 56);
    number|= (buffer[1] << 48);
    number|= (buffer[2] << 40);
    number|= (buffer[3] << 32);
    number|= (buffer[4] << 24);
    number|= (buffer[5] << 16);
    number|= (buffer[6] << 8);
    number|= buffer[7];
    return number;
}

我收到警告C4293&#39;&lt;&lt;&quot;&#39;:班次计数为负数或太大,未定义的行为&#34;最高位移位的四次; 这是一个我可以放心忽略的警告,因为编译器没有认识到我使用的是无符号64位int吗?我认为它不是。但那我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

不,你不能忽视它。操作数buffer[i]的类型为unsigned char,可能会提升为int(如果不是int,则为unsigned int)。如果56大于或等于int的位宽,则移位为UB。

你需要写static_cast<unsigned long long>(buffer[0]) << 56等等,所以在移位之前,操作数至少为64位

答案 1 :(得分:1)

在表达式中使用时,unsigned char值会提升为int s。试图将int移位56位显然不会很有效率。

你必须更明确:

 unsigned long long number= ((unsigned long long)buffer[0] << 56);
    number|= ((unsigned long long)buffer[1] << 48);

......等等。在轮班操作发生之前,您必须强制转换为unsigned long long

答案 2 :(得分:0)

我认为最好明确说明意图并让编译器的优化器发挥其魔力:

log(n)

unsigned long long版本的汇编程序输出示例(未内联时):

DispatchQueue.main.async(execute: { [weak weakSelf = self] () -> Void in
            weakSelf!.tableView.reloadData()
        })

答案 3 :(得分:0)

更改这样的代码:

//unsigned long long number= (buffer[0] << 56);
unsigned long long number= ((buffer[0] << 31) << 25);