Название: Проблемы с разыменованием Отправлено: juvf от Январь 06, 2011, 14:19 вот код
Код: //alt_u16 - это тип данных, беззнаковое двухбайтное, можно считать что unsigned short шагаю дебагом по строчке. когда указатель р указывает на четный адрес, то изменяется значение по адресам р и р+1, когда р указывает на нечетный адрес, изменяется значение по адресам р-1 и р. Чё-то тут с выравниванием связанно. Как это победить? компилятор nios2-elf-gcc. Но в доках на компилятор нет ни каких ограничений по поводу разименовывания. Название: Re: Проблемы с разыменованием Отправлено: pastor от Январь 06, 2011, 15:39 Ну а как ты хотел. Все верно. У тебя же массив char же (char == 1 байт), а записываешь двухбайтные данные.
bufRecive[0] - адресс 0 элемента массива. Цитировать alt_u16* p = reinterpret_cast<alt_u16*>(&bufRecive[0]); *p = 0x1234; данные попали в bufRecive[0] и bufRecive[1] bufRecive[1] - адресс 1 элемента массива. По этому адресу уже содержатся данные с первой операции (это ведь второй байт) Цитировать p = reinterpret_cast<alt_u16*>(&bufRecive[1]); *p = 0x7890; данные попали в bufRecive[1] и bufRecive[2] и т.д. Название: Re: Проблемы с разыменованием Отправлено: Fat-Zer от Январь 06, 2011, 15:53 //оффтоп
А можете рассказать, какой сокральный смысл в использование reinterpretate_cast в данном случае? Чем он правильней statiс_cast'а и чем лучше олдскульного приведения? (я так понял alt_u16 это тайпдеф или дефайн...) Зарание спасибо. Название: Re: Проблемы с разыменованием Отправлено: brankovic от Январь 06, 2011, 19:23 Скорее всего процессор игнорирует младший бит для указателя на слово. Но зачем вообще понадобилось писать двухбайтовые значения с интервалом в байт?! Наверное имелось ввиду &buf[0], &buf[2], ...
Название: Re: Проблемы с разыменованием Отправлено: juvf от Январь 06, 2011, 22:38 Цитировать Цитировать p = reinterpret_cast<alt_u16*>(&bufRecive[1]); *p = 0x7890; данные попали в bufRecive[1] и bufRecive[2] Поэкспериментировал еще с прогой.... проблема не в касте, давайте без каста и без тайпдефов привиду пример Код: char array[10]; //в отладчике посмотрел адрес размещения массива, пусть будет 0x00801C4 после последней строчки я ожидаю изменение по адресам 0x00801C5 и 0x00801C6. Т.е. должно быть array[0] = 0х78, array[1] = 0х56. Но адрес 0x00801C6 (элемент array[2] ) остается без изменения а меняются 0x00801C4 и 0x00801C5, т.е. array[0] = 0х78, array[1] = 0х56. Вот в этом проблема. Цитировать Скорее всего процессор игнорирует младший бит для указателя на слово. Ну вот это уже похоже на истину. Как бы это побороть?ps офтоп Цитировать Но зачем вообще понадобилось писать двухбайтовые значения с интервалом в байт?! Такой протокол обмена, я его реализую. Пакет примерно такой: первый байт кадра - адрес, следующие два это длинна пакета, слудеющие два команда, следующий ....., следующие 4 байта параметр Х, следующие 4 байта - это температура в формате float, .... и т.д. Во многих протоколах подобное встречал. Раньше парсил подобными кодомКод: char array[100]; но решил попробовать явным преобразованием типов (int*)(array+16) = count; , но не тут-то было. Цитировать А можете рассказать, какой сокральный смысл в использование reinterpretate_cast в данном случае? Чем он правильней statiс_cast'а и чем лучше олдскульного приведения? Да сам толком не понимаю. НА си делал явные приведения, типа (int*)(bufRecive[1]). Но в с++ это типа плохой стиль. Есть касты. Сто раз перечитал про касты, запомнил тока одно - в с++ пользуй касты. А почему ... минут 10 помнил после прочтения учебников, потом просто лишняя инфа из головы пропадала. Осталось только "В с++ пользуй касты" Почему не static_cast? А не работает статик каст с базовыми типами. Компилятор ругается на такой каст Код: char array[10]; Название: Re: Проблемы с разыменованием Отправлено: brankovic от Январь 06, 2011, 23:24 Цитировать Скорее всего процессор игнорирует младший бит для указателя на слово. Ну вот это уже похоже на истину. Как бы это побороть?Никак. Т.е. на данной архитектуре невозможно записать по нечётному указателю слово. gcc об этом не знает и генерит неправильный код. Цитировать Но зачем вообще понадобилось писать двухбайтовые значения с интервалом в байт?! Такой протокол обмена, я его реализую. Пакет примерно такой: первый байт кадра - адрес, следующие два это длинна пакета, слудеющие два команда, следующий ....., следующие 4 байта параметр Х, следующие 4 байта - это температура в формате float, .... и т.д. Во многих протоколах подобное встречал.я примерно так делаю: Код
Вообще не хочу пугать, но reinterpret_cast не всегда работает к тому же. С ходу пример не приведу, но был случай, когда пришлось на union заменить (причина -- strict aliasing rules). Название: Re: Проблемы с разыменованием Отправлено: Fat-Zer от Январь 07, 2011, 02:22 Цитировать Скорее всего процессор игнорирует младший бит для указателя на слово. Ну вот это уже похоже на истину. Как бы это побороть?Цитировать Цитировать Ну и обычные массивы - тоже плохой для цпп стиль, не говоря уже о том, чтобы писать слова в байты...А можете рассказать, какой сокральный смысл в использование reinterpretate_cast в данном случае? Чем он правильней statiс_cast'а и чем лучше олдскульного приведения? Да сам толком не понимаю. НА си делал явные приведения, типа (int*)(bufRecive[1]). Но в с++ это типа плохой стиль. Есть касты. Сто раз перечитал про касты, запомнил тока одно - в с++ пользуй касты. А почему ... минут 10 помнил после прочтения учебников, потом просто лишняя инфа из головы пропадала. Осталось только "В с++ пользуй касты" Цитировать Почему не static_cast? А не работает статик каст с базовыми типами. Компилятор ругается на такой каст мда... тупил....Название: Re: Проблемы с разыменованием Отправлено: pastor от Январь 07, 2011, 05:35 А что мешает создать массив тех же alt_u16 и далее огранизовывать с ним работу?
Код
Название: Re: Проблемы с разыменованием Отправлено: Igors от Январь 07, 2011, 09:25 Цитировать Скорее всего процессор игнорирует младший бит для указателя на слово. Ну вот это уже похоже на истину. Как бы это побороть?Код содержимое buf AA 34 12 AA .. Вполне может врать отладчик - стоит проверить Название: Re: Проблемы с разыменованием Отправлено: Fat-Zer от Январь 07, 2011, 09:48 А меня тут ещё озарение посетило... А разве не для таких вещей изобрели структуры?
Название: Re: Проблемы с разыменованием Отправлено: juvf от Январь 07, 2011, 11:04 О!!! :o На сколько мир стал понятней! Всем спасибо. :)
brankovic спасибо за совет, попробую ваш пример. А что мешает создать массив тех же alt_u16 и далее огранизовывать с ним работу? Ни чего не мешает. Привычка. Обычно пишу на 8-ми разрядных микроЭВМ, типа AVR или MSP430. Там ОЗУ как правило байтами исчисляется, например 256 байт. Поэтому приходится экономить на спичках. А тут NIOS II, у него 8 Мб озу. Вполне можно пожертвовать несколькими кб памяти. Тоже хорошие решение. Спасибо за совет.Цитировать Предупреждать надо, что дело не на x86 происходит... Цитировать Предупреждать надо, что муж волшебник. :) сори, но я и не говорил что на х86. Тем более я указал компилятор nios2-elf-gcc - уже понятно что не х86.Цитировать Ну и обычные массивы - тоже плохой для цпп стиль, не говоря уже о том, чтобы писать слова в байты... На х86 для этих целей использую QByteArray. В ниосе нет Qt. Вначале в качестве ByteArray использовал std::string, но чё то какие-то глюки были с стрингом, временно решил массив сделать. Для маленьких процессоров обычно с++ это экзотика, не говоря уже о стл. Поэтому иногда стл может быть реализован с багами. А вообще мне тоже массивы не нравятся. А что можно использовать в качестве ByteArray? Можно конечно самому класс написать, но .... Название: Re: Проблемы с разыменованием Отправлено: brankovic от Январь 07, 2011, 13:04 А что мешает создать массив тех же alt_u16 и далее огранизовывать с ним работу? После первого поста тоже так подумал, но потом последовало описания "протокола": Пакет примерно такой: первый байт кадра - адрес, следующие два это длинна пакета, слудеющие два команда, следующий ....., следующие 4 байта параметр Х, следующие 4 байта - это температура в формате float, .... и т.д. -- пакуются элементы переменной длины. А про экономию на спичках сам не вполне понял. А меня тут ещё озарение посетило... А разве не для таких вещей изобрели структуры? казалось бы, можно сделать так: struct packet { char address; //здесь дырка 1 байт short length; short command; //а здесь дырка 2 байта float temper; ... } p = {'0', 1, 2, .3, ...}; send (socket, (void*) &p, sizeof (p)); //посылаем байты структуры, как они лежат в памяти Но нет, если так делать, то в пакет попадут дырки и формат пакета будет нарушен. Название: Re: Проблемы с разыменованием Отправлено: BRE от Январь 07, 2011, 13:40 Но нет, если так делать, то в пакет попадут дырки и формат пакета будет нарушен. Так нельзя делать не только из-за выравнивания полей структуры, его всегда можно сделать равным одному байту, а больше из-за того, что идет отправка данных без перевода в сетевой порядок байт. На другой архитектуре можно легко получить кашу.Вообще мне не совсем понятно почему в данном случае не использовать потоки (stream)? QDataStream специально сделан для создания безопасного пакета данных, который можно спокойно передавать между разными архитектурами и декодировать его на них. Название: Re: Проблемы с разыменованием Отправлено: brankovic от Январь 07, 2011, 13:50 идет отправка данных без перевода в сетевой порядок байт. На другой архитектуре можно легко получить кашу. целых 50% шанс угадать! Если серьёзно, то там какая-то nios2, я думал там типа usb-протокола, send написал, потому что больше умных слов не знаю :) Вообще мне не совсем понятно почему в данном случае не использовать потоки (stream)? QDataStream кажется упоминалось "нет qt" из-за выравнивания полей структуры, его всегда можно сделать равным одному байту ??? оффтоп конечно, но нельзя ли пояснить? Название: Re: Проблемы с разыменованием Отправлено: Igors от Январь 07, 2011, 14:01 из-за выравнивания полей структуры, его всегда можно сделать равным одному байту ??? оффтоп конечно, но нельзя ли пояснить?Код Хотя если речь идет об экзотических процессорах (напр не умеющих писать по нечетному адресу) - это не спасет А вообще конечно - передача "структурой" не метод, придется затем возиться с индианой, все равно ничего не выиграем. Конечно QDataStream или др. класс умеющий читать/писать в поток |