When converting from a signed char
to unsigned int
(or other larger unsigned type) the language specifies sign extension happens first. To avoid that, cast the char
to unsigned char
as your first step. You shouldn't need any other cast - the increase in size should happen automatically.
Wrong sign extension c++/qt
-
19-06-2023 - |
Question
I am running the following code on an Desktop x64 Intel architecture (gcc compiler, linux) and on an RaspberryPi Arm (gcc cross compiler).
quint32 id;
id=((quint32)ref[1]);
id|=((quint32)ref[2])<<8;
id|=((quint32)ref[3])<<16;
id|=((quint32)ref[4])<<24;
where ref is a QByteArray.
I noticed, that despite of casting quint32 (which is unsigned int) my Pc do the sign extension which causes error, when the given byte is a negative number. My code runs fine on Arm. Why does this happens? I thought casting should prevent this. Doesn't it?
id|=((quint32)ref[4])<<24;
disassembly:
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)
I have also noticed, that compiler uses QByteRef return value instead of char. But it should not cause any error i guess.
from QByteArray help page :
QByteRef operator[](int i)
char operator[](int i) const
QByteRef operator[](uint i)
char operator[](uint i) const
Thanks in advance
La solution
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow