ViKo 1 14 декабря, 2010 Опубликовано 14 декабря, 2010 · Жалоба Имею буфер приема от панели управления (в составе структуры 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 Так оно работает, но непонятки остались... Теперь обе переменные размножили знак. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 14 декабря, 2010 Опубликовано 14 декабря, 2010 · Жалоба Имею буфер приема от панели управления (в составе структуры 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]; даст то же самое. Во-вторых, исходный операнд у вас беззнаковый, т.е. знака там нет в принципе, поэтому расширять нечего и по правилам стандартных преобразований типов компилятор просто честно забивает нулями старшие биты. Когда вы поменяли тип источника на знаковый, то знак появился и опять же по тем же правилам стандартных преобразований С/С++ компилятор должен выполнить расширение знака. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 декабря, 2010 Опубликовано 14 декабря, 2010 · Жалоба зачем ручное преобразование типов - ведь 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; Как видите, нашлось что расширять :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 15 декабря, 2010 Опубликовано 15 декабря, 2010 · Жалоба int32_t KeyCnt = (int8_t) FPI.FP_RBf[1]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 15 декабря, 2010 Опубликовано 15 декабря, 2010 · Жалоба int32_t KeyCnt = (int8_t) FPI.FP_RBf[1]; Да, проходит и такое. А я уж было "изобрел" конструкцию "с двойным преобразованием" :) int32_t KeyCnt = (int32_t)(int8_t)FPI.FP_RBf[1]; А, может, так, как я написал, надежнее, правильнее? Все-таки, конкретное указание... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 16 декабря, 2010 Опубликовано 16 декабря, 2010 · Жалоба int32_t KeyCnt = (int32_t)(int8_t)FPI.FP_RBf[1]; А, может, так, как я написал, надежнее, правильнее? Все-таки, конкретное указание... Второе преобразование (int32_t) компилятор сделает сам (причем молча - это вполне штатная ситуация). Так что от наличия или отсутствия (int32_t) в приведении ничего не изменится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 декабря, 2010 Опубликовано 16 декабря, 2010 · Жалоба Второе преобразование (int32_t) компилятор сделает сам (причем молча - это вполне штатная ситуация). Так что от наличия или отсутствия (int32_t) в приведении ничего не изменится. Полностью согласен. Правая часть выражения должна быть приведена к размерности переменной в левой части. Остался маленький вопросик - преобразование беззнакового байта в знаковый - это просто "подмена представления", не вызывающая у компилятора даже варнинга? Все-таки, например, 255 превращается в -1, и ничего страшного? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 65 16 декабря, 2010 Опубликовано 16 декабря, 2010 · Жалоба Остался маленький вопросик - преобразование беззнакового байта в знаковый - это просто "подмена представления", не вызывающая у компилятора даже варнинга? Все-таки, например, 255 превращается в -1, и ничего страшного? С чего компилятору тут ругаться - ведь ему же программистом указано. Предупреждения компилятор выдает, когда имеет место неявное преобразование, которое делается как бы скрытно и поэтому может привести к неожиданному (для программиста) поведению кода. Если программист сам руками указал, что этот объект в данном случае трактовать так и не иначе, то компилятор должен выполнять. Другое дело, что сишная форма явного преобразования типов этакая "неброская", ее иногда легко пропустить при чтении кода - похожа на аргумент выражения или функции. Поэтому в С++ специально ввели новый синтаксис для явного преобразования типов, который своим безобразным видом сразу привлекает к себе внимание - чтобы в случае чего можно быстро увидеть потенциально опасные места. Ну, и еще разделили единую форму на две различные, отличающиеся степенью опасности: static_cast и reinterpret_cast. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться