我在Desktop x64 Intel架构(gcc编译器,linux)和RaspberryPi Arm(gcc交叉编译器)上运行以下代码。
quint32 id;
id=((quint32)ref[1]);
id|=((quint32)ref[2])<<8;
id|=((quint32)ref[3])<<16;
id|=((quint32)ref[4])<<24;
参考是 QByteArray 。
我注意到,尽管使用了quint32(无符号整数),但当给定的字节为负数时,我的Pc会执行符号扩展,这会导致错误。我的代码在Arm上正常运行。为什么会这样? 我认为施法可以防止这种情况发生。不是吗?
id|=((quint32)ref[4])<<24;
拆卸:
mov -0x160(%rbp),%rax
mov $0x4,%esi
mov %rax,%rdi
callq 0x425af0 <QByteArray::operator[](int)>
mov %rax,%rcx
mov %edx,%eax
mov %rcx,-0x170(%rbp)
mov %eax,-0x168(%rbp)
mov -0x170(%rbp),%rax
mov %rax,-0x40(%rbp)
mov -0x168(%rbp),%rax
mov %rax,-0x38(%rbp)
lea -0x40(%rbp),%rax
mov %rax,%rdi
callq 0x425aa0 <QByteRef::operator char() const>
movsbl %al,%eax #sign extension.
shl $0x18,%eax
or %eax,-0x148(%rbp)
我也注意到,编译器使用QByteRef返回值而不是char。但它不应该导致任何错误。
来自QByteArray帮助页面:
QByteRef operator[](int i)
char operator[](int i) const
QByteRef operator[](uint i)
char operator[](uint i) const
提前致谢
答案 0 :(得分:2)
从签名的char
转换为unsigned int
(或其他较大的无符号类型)时,语言会指定符号扩展首先发生。为避免这种情况,请将char
转换为unsigned char
作为您的第一步。你不应该需要任何其他演员 - 大小的增加应该自动发生。