Неверное расширение знака C++/qt
Я запускаю следующий код на архитектуре Intel для настольных компьютеров x64 (компилятор 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;
где ref является QByteArray.
Я заметил, что, несмотря на приведение типа quint32 (который является беззнаковым int), мой 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
заранее спасибо
1 ответ
При конвертации из подписанного char
в unsigned int
(или другой больший тип без знака) язык определяет, что расширение знака происходит первым. Чтобы избежать этого, бросьте char
в unsigned char
как твой первый шаг. Вам не нужно никакого другого приведения - увеличение размера должно происходить автоматически.