这是我(想要)用于解码无符号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吗?我认为它不是。但那我该如何解决这个问题?
答案 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);