Неверное расширение знака 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 как твой первый шаг. Вам не нужно никакого другого приведения - увеличение размера должно происходить автоматически.

Другие вопросы по тегам