Название: двухбайтное число в quint16 Отправлено: Edynchik от Февраль 10, 2015, 21:21 Есть такая ситуация, число лежит в массиве побайтно младшими вперед например 0x020e, т.е.
Код: buf[0] = 0x0e;buf[1] =0x02; Код: quint16 n = (quint16)buf[1]; Название: Re: двухбайтное число в quint16 Отправлено: Old от Февраль 10, 2015, 21:23 Есть такая ситуация, число лежит в массиве побайтно младшими вперед например 0x020e, т.е. buf[0]Код: buf[0] = 0x0e;buf[1] =0x02; Код: quint16 n = (quint16)buf[1]; Название: Re: двухбайтное число в quint16 Отправлено: Edynchik от Февраль 10, 2015, 21:24 да и buf[0] пробовал выдает не 2 а 14, что то тоже не то, там вроде указатель должен быть???
Название: Re: двухбайтное число в quint16 Отправлено: kambala от Февраль 10, 2015, 21:35 наверное что-то типа такого должно быть:
Код
Название: Re: двухбайтное число в quint16 Отправлено: Edynchik от Февраль 10, 2015, 21:51 спасибо, правда сейчас нет под рукой компилятора, завтра проверю.
Название: Re: двухбайтное число в quint16 Отправлено: Пантер от Февраль 10, 2015, 22:19 qFromLittleEndian, qFromBigEndian.
Название: Re: двухбайтное число в quint16 Отправлено: juvf от Февраль 11, 2015, 12:55 наверное что-то типа такого должно быть: будет работать до поры до времени, пока адрес buf выровнен. если не проследить за выравниванием, то словите ошибку во время выполнения, причем трудноуловимую. лучше не баловаться подобным приведением типа, а сделать что-то типаКод
quint16 n = buf[0] + (buf[1] >> 8); Название: Re: двухбайтное число в quint16 Отправлено: Igors от Февраль 11, 2015, 13:23 наверное что-то типа такого должно быть: будет работать до поры до времени, пока адрес buf выровнен. если не проследить за выравниванием, то словите ошибку во время выполнения, причем трудноуловимую. лучше не баловаться подобным приведением типа, а сделать что-то типаКод
quint16 n = buf[0] + (buf[1] >> 8); Код Неужели *dst не будет правильно читаться/писаться если стоит по нечетному адресу ? :) Название: Re: двухбайтное число в quint16 Отправлено: juvf от Февраль 15, 2015, 13:46 Что за мифическое выравнивание? Давайте проверим А не везде эти прагмы работают. Например последний случай на UC-8410 = http://www.moxa.com/product/UC-8410.htm (http://UC-8410 = http://www.moxa.com/product/UC-8410.htm), ARM процессор, эти прагмы не работают. Выравнивание 4.я присал Цитировать если не проследить за выравниванием, то словите ошибку во время выполнения вы же мне привели код, в котором проследили за выравниванием. Во вторых ваш тестовый код не выявит ни чего.Код: CTest test; лучше так проверить Код: #pragma pack(push, 1) Название: Re: двухбайтное число в quint16 Отправлено: Igors от Февраль 15, 2015, 15:34 лучше так проверить Давайте так (чуть изменил печать)Код Вывод Цитировать dst = 0x1234 dst = 0xabcd // если buf на нечетном адресе, то тут ловим ошибку... пишется куданить в сторону. допустим записали в адрес buf-1 С чего Вы это взяли ??? Пишется начиная с того адреса который дали. Просто если он не выровнен, процессор затратит больше времени ("штрафные такты" и все такое) - но никакой ошибки мы не словимНазвание: Re: двухбайтное число в quint16 Отправлено: Old от Февраль 15, 2015, 18:34 С чего Вы это взяли ??? Пишется начиная с того адреса который дали. Просто если он не выровнен, процессор затратит больше времени ("штрафные такты" и все такое) - но никакой ошибки мы не словим Вы ошибаетесь. Точнее пытаетесь судить обо всем по своим знаниям.А человек выше даже указал процессор, который не умеет читать не выровненные данные. Название: Re: двухбайтное число в quint16 Отправлено: juvf от Февраль 16, 2015, 09:09 лучше так проверить Давайте так (чуть изменил печать)Код Вывод Цитировать dst = 0x1234 dst = 0xabcd // если buf на нечетном адресе, то тут ловим ошибку... пишется куданить в сторону. допустим записали в адрес buf-1 С чего Вы это взяли ??? Пишется начиная с того адреса который дали. Просто если он не выровнен, процессор затратит больше времени ("штрафные такты" и все такое) - но никакой ошибки мы не словимЦитировать quint16 n = *(reinterpret_cast<quint16 *>(buf)); Видать ТС новичок и плохо разбирается в привидении типа. Он этот код использует у себя.... и возможно его buf[0] выровнен к 4. Или у него процессор 8-ми битный. Он в своем коде ни когда не словит ошибку. Я предостерёг, что пользуясь таким кодом нужно следить за выравниванием. В чем я не прав? Ни кто ему не сказал сделай такЦитировать #pragma pack(push, 1) Нужно понимать, что на конкретной архитектуре выравнивание может быть 2 или 4. На некоторых архитектурах не работают прагмы. То, что вы проверили на конкретной архитектуре и заработало - это не значит что будет работать везде. На AVR без прагмы всё будет работать. char buf[128] = {0}; #pragma pack(pop) quint16 n = *(reinterpret_cast<quint16 *>(buf) ТС использует такое приведение типа без прагмы, как посоветовали, код будет работать. ТС усвоит урок. Потом в другом месте сделает также (или использует этот код)... и обратится по невыровненным данным.... выстрелит себе в ногу. "Прозанимается любовью" с этой багой.... и соскочит на жаву. А потом возникают на форумах холивары, что с/с++ гавно. Вы в своем коде проследили за выравниванием, т.е. вы прагмами изменили выравнивание к 1. Я говорю тоже самое - нужно учитывать выравнивание. ps Код: *dst = 0xABCD; Название: Re: двухбайтное число в quint16 Отправлено: Igors от Февраль 16, 2015, 13:25 Цитированием не злоупотребляйте плз
ТС использует такое приведение типа без прагмы, как посоветовали, код будет работать. ТС усвоит урок. Потом в другом месте сделает также (или использует этот код)... и обратится по невыровненным данным.... выстрелит себе в ногу. "Прозанимается любовью" с этой багой.... и соскочит на жаву. А потом возникают на форумах холивары, что с/с++ гавно. Трогательная забота о ТС - но у него своя голова есть :) А захочет на жабу - тем лучше, слабаки не нужны. Еще до PowerPC я работал на Mac, тогда проц motorola не умел писать в нечет - но он выбрасывал исключение "address must be even". Если опять такой появится и возникнет необходимость его поддержки (Вашу ссылку открыть не могу, но гипотетически это возможно)- ну тогда много чего полетит, и много чего придется переписывать. А до этого не стоит шарахаться от мифических угроз, типа "а вот есть такой проц где.. и тогда, тогда... о ужас!!!" :) Стандарт запрещает писать по невыровненному адресу? Насколько мне известно - нет. Ну и все, а там посмотрим. Заказ на работу с причудливым процом еще надо получить.Вот куда более реальная проблема: на Вындоуз тип long всегда 4 байта. а вот на Mac он 8 в 64-bit но 4 в 32-bit. Связанные с этим ошибки совсем не редки. Следуя Вашей логике нужно немедленно истребить все long заменив на что-то типа SInt32. Но сделали ли Вы это? :) Название: Re: двухбайтное число в quint16 Отправлено: juvf от Февраль 16, 2015, 15:55 Стандарт запрещает писать по невыровненному адресу? Насколько мне известно - нет. Ну и все, а там посмотрим. Заказ на работу с причудливым процом еще надо получить. Если на конкретной архитектуре выравнивание 4, то с подобным приведением типа вы должны позаботиться о выравнивании. либо вы должны чтобы buf был кратен 4, либо вы должны указать прагмой нужное выравнивание. выравнивание 4 - это не мифический процессор. Вот http://www.moxa.com/product/UC-8410.htm - вполне не мифическая микроЭВМ с немифическим Intel XScale IXP435 533 MHz processor. Цитировать Что за мифическое выравнивание? Давайте проверим Смешно както.... "Что за мифическое выравнивание? Давайте проверим" - и тут же приводите проверочный код, в котором вы позаботились о выравнивании. Если это выравнивание мифическое, зачем вы прагмой изменили выравнивание к 1? Ваш проверочный код выровнен к 1. И данные выровнены к 1. Можно спокойно обращаться к адресам кратным 1. Вы проверьте без выравнивания.Код Цитировать #pragma pack(push, 1) struct CTest { char ch; char buf[128]; }; #pragma pack(pop) ... CTest test; quint16 * dst = (quint16 *) &test.buf[0]; *dst = 5; qDebug() << dst << *dst; Неужели *dst не будет правильно читаться/писаться если стоит по нечетному адресу ? Цитировать шарахаться от мифических угроз, типа "а вот есть такой проц где.. и тогда, тогда... о ужас!!!" От каких мифических угроз? На любом процессоре и любой архитектуре, если делаешь привидение типа Код: quint16 n = *(reinterpret_cast<quint16 *>(buf)); С ваших слов, выравнивание это миф и о нем заботиться не нужно. И в качестве доказательства приводите пример с выровненными данными. В чем смысл? Название: Re: двухбайтное число в quint16 Отправлено: Igors от Февраль 16, 2015, 17:37 От каких мифических угроз? На любом процессоре и любой архитектуре, если делаешь привидение типа Возможно Вы имели ввиду нечто типаКод: quint16 n = *(reinterpret_cast<quint16 *>(buf)); Код Да, это неверно, n будет совсем не test.val, до которого еще 1 байт. Да, если сделаем #pragma pack 1 для CTest - тогда будет верно. С этим никто не спорит, но это совсем не значит что reinterpret_cast что-то "не так приводит" или читается/пишется куда-то "налево". reinterpret_cast четко работает с тем адресом что дали. Напр если это &test.val - то он и будет читаться/писаться, какое бы выравнивание ни стояло. Если на конкретной архитектуре выравнивание 4, то с подобным приведением типа вы должны позаботиться о выравнивании. либо вы должны чтобы buf был кратен 4, либо вы должны указать прагмой нужное выравнивание. выравнивание 4 - это не мифический процессор. Вот http://www.moxa.com/product/UC-8410.htm - вполне не мифическая микроЭВМ с немифическим Intel XScale IXP435 533 MHz processor. Я открыл ссылку, поискал "align" - не нашел. Пожалуйста "ткните носиком". Название: Re: двухбайтное число в quint16 Отправлено: Old от Февраль 16, 2015, 18:08 Есть куча армов, которые не могут обращаться по не выравненным адресам. Вместо доступа будет генерироваться прерывание.
Для правильного доступа, нужно что бы оперант в памяти был выравнен на свою длину, т.е. хотим читать 16 битное число из памяти, оно должно быть выравненно на 2 байта, если 32 битное - то на 4. Нет получи прерывание. Конечно можно самому эмулировать чтение через побайтовое, но это лишние такты. Зная это, компиляторы генерируют правильный код, пока программист не дотягивается до ручного привидения типов, там компилятор становится бессильным и программист должен все контроллировать сам. Название: Re: двухбайтное число в quint16 Отправлено: Igors от Февраль 16, 2015, 19:06 Да, действительно, juvf прав, есть такие звери. Вот нашел популярное описание
http://www.aleph1.co.uk/chapter-10-arm-structured-alignment-faq (http://www.aleph1.co.uk/chapter-10-arm-structured-alignment-faq) Причем да, могут и "втихаря" неверно читать/писать. Признаю - был неправ :) Название: Re: двухбайтное число в quint16 Отправлено: juvf от Февраль 16, 2015, 19:08 проверил на дэсктопе код
Код: char ch[8] = {1,2,3,4,5,6,7,8}; Запустил этот код на девайсе с процессором AT91SAM7S256 (ARM архитектура) - на строке с reinterpret_cast процессор завис. печалька. Ну да ладно.... SAM7 наверно мифический.... собрал такой код в UC-8410 (процессор Intel XScale IXP435, ARM-архитектура) Код: int main() Код: root@gp1:/home/juvf# ./test2 Название: Re: двухбайтное число в quint16 Отправлено: juvf от Февраль 16, 2015, 19:16 Причем да, могут и "втихаря" неверно читать/писать. Признаю - был неправ :) Да да да.... Самое печальное, что некоторые именно втихаря. Ладно сам7 сразу завис. А так втихоря уйдет в сторону.... замучаешься искать. :)Название: Re: двухбайтное число в quint16 Отправлено: Igors от Февраль 17, 2015, 09:51 Запустил этот код на девайсе с процессором AT91SAM7S256 (ARM архитектура) - У Вас там что, тазик с процессорами ? :).. ... собрал такой код в UC-8410 (процессор Intel XScale IXP435, ARM-архитектура) |