Перейти к содержанию
    

Преобразовать uint8_t в int32_t

Имею буфер приема от панели управления (в составе структуры FPI)

uint8_t FP_RBf[2];

Хочу прочитать этот буфер и вызвать функцию по значению первого байта, и значение второго байта передать в функцию, как int32_t.

uint32_t KeyNum = (uint32_t)FPI.FP_RBf[0];
int32_t  KeyCnt = (int32_t) FPI.FP_RBf[1];
FpKey_hand[KeyNum](KeyCnt);

Однако заметил, что при считывании RBf[1] компилятор использует команду LDRB, а не LDRSB

;;;295      int32_t  KeyCnt = (int32_t) FPI.FP_RBf[1];
0001a4  78c0              LDRB     r0,[r0,#3] ; FPI

Т.е. не происходит знакового расширения байта. Как сделать правильно?

 

Заменил тип в буфере на int8_t. Получилось следующее:

;;;294      uint32_t KeyNum = (uint32_t)FPI.FP_RBf[0];
0001a4  f9901002          LDRSB    r1,[r0,#2] ; FPI
;;;295      int32_t  KeyCnt = (int32_t)FPI.FP_RBf[1];
0001a8  f9900003          LDRSB    r0,[r0,#3] ; FPI

Так оно работает, но непонятки остались... Теперь обе переменные размножили знак.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имею буфер приема от панели управления (в составе структуры FPI)

uint8_t FP_RBf[2];

Хочу прочитать этот буфер и вызвать функцию по значению первого байта, и значение второго байта передать в функцию, как int32_t.

uint32_t KeyNum = (uint32_t)FPI.FP_RBf[0];
int32_t  KeyCnt = (int32_t) FPI.FP_RBf[1];
FpKey_hand[KeyNum](KeyCnt);

Однако заметил, что при считывании RBf[1] компилятор использует команду LDRB, а не LDRSB

;;;295      int32_t  KeyCnt = (int32_t) FPI.FP_RBf[1];
0001a4  78c0              LDRB     r0,[r0,#3]; FPI

Т.е. не происходит знакового расширения байта. Как сделать правильно?

Не знаток АРМа, но навскидку: во-первых, зачем ручное преобразование типов - ведь

 

uint32_t KeyNum = FPI.FP_RBf[0];

 

даст то же самое.

 

Во-вторых, исходный операнд у вас беззнаковый, т.е. знака там нет в принципе, поэтому расширять нечего и по правилам стандартных преобразований типов компилятор просто честно забивает нулями старшие биты. Когда вы поменяли тип источника на знаковый, то знак появился и опять же по тем же правилам стандартных преобразований С/С++ компилятор должен выполнить расширение знака.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

зачем ручное преобразование типов - ведь

uint32_t KeyNum = FPI.FP_RBf[0];

даст то же самое.

Ну, эта строка написана "по инерции" за компанию, чтобы не отличалась от следующей.

Вот какое решение нашлось, для буфера из uint8_t

;;;305      int8_t temp = FPI.FP_RBf[1];  
0001a4  f9900003          LDRSB    r0,[r0,#3]; FPI
;;;306      int32_t KeyCnt = (int32_t)temp;

Как видите, нашлось что расширять :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

int32_t  KeyCnt = (int8_t) FPI.FP_RBf[1];

Да, проходит и такое.

А я уж было "изобрел" конструкцию "с двойным преобразованием" :)

int32_t KeyCnt = (int32_t)(int8_t)FPI.FP_RBf[1];

А, может, так, как я написал, надежнее, правильнее? Все-таки, конкретное указание...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

int32_t KeyCnt = (int32_t)(int8_t)FPI.FP_RBf[1];

А, может, так, как я написал, надежнее, правильнее? Все-таки, конкретное указание...

Второе преобразование (int32_t) компилятор сделает сам (причем молча - это вполне штатная ситуация). Так что от наличия или отсутствия (int32_t) в приведении ничего не изменится.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Второе преобразование (int32_t) компилятор сделает сам (причем молча - это вполне штатная ситуация). Так что от наличия или отсутствия (int32_t) в приведении ничего не изменится.

Полностью согласен. Правая часть выражения должна быть приведена к размерности переменной в левой части.

Остался маленький вопросик - преобразование беззнакового байта в знаковый - это просто "подмена представления", не вызывающая у компилятора даже варнинга? Все-таки, например, 255 превращается в -1, и ничего страшного?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Остался маленький вопросик - преобразование беззнакового байта в знаковый - это просто "подмена представления", не вызывающая у компилятора даже варнинга? Все-таки, например, 255 превращается в -1, и ничего страшного?

С чего компилятору тут ругаться - ведь ему же программистом указано. Предупреждения компилятор выдает, когда имеет место неявное преобразование, которое делается как бы скрытно и поэтому может привести к неожиданному (для программиста) поведению кода. Если программист сам руками указал, что этот объект в данном случае трактовать так и не иначе, то компилятор должен выполнять.

 

Другое дело, что сишная форма явного преобразования типов этакая "неброская", ее иногда легко пропустить при чтении кода - похожа на аргумент выражения или функции. Поэтому в С++ специально ввели новый синтаксис для явного преобразования типов, который своим безобразным видом сразу привлекает к себе внимание - чтобы в случае чего можно быстро увидеть потенциально опасные места. Ну, и еще разделили единую форму на две различные, отличающиеся степенью опасности: static_cast и reinterpret_cast.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...