|
|
  |
Ошибка при копировании структур, Почему-то виснет при копировании вложенных структур |
|
|
|
Oct 20 2014, 10:41
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Структура типа im_rect является вложенной в структуре im_widget. При создании массива из элементов im_widget внутренняя структура im_rect InnerRect не копируется (прибор виснет при отладке) в случае если элементы im_widget в одном массиве. В Visual Studio все работает, а в Visual DSP виснет. Что делать? И как Вы делаете копирование структур? Читал, что в старых компиляторах на это было ограничение. Можно memcpy или memmove. Но хочется разобраться в таком поведении контроллера. Код typedef int_fast16_t im_int;
typedef struct { im_int Left; im_int Top; im_int Right; im_int Bottom; } im_rect;
typedef struct { im_int Type; im_rect OuterRect; im_rect InnerRect; void * Widget; im_int State; char * Title; char * Text; char * Hint; pt2Function Function; void * AddInf; im_pixel BkPixel; uchar AutoSize; pt2Function DrawFunction; } im_widget;
im_rect TestRect = { 5, 6, 7, 8 }; im_widget wFKey[4];
wFKey[0].InnerRect.Left = 5;
memcpy(&wFKey[1].InnerRect, &wFKey[0].InnerRect, sizeof(im_rect)); // Работает wFKey[1].InnerRect = wFKey[0].InnerRect; // Виснет wFKey[1].InnerRect = TestRect; // Работает Т.е. виснет при копировании вложенных структур внутри массива.
|
|
|
|
|
Oct 20 2014, 13:07
|
Местный
  
Группа: Свой
Сообщений: 271
Регистрация: 6-12-11
Из: Taganrog
Пользователь №: 68 701

|
Думаю, надо точно убедиться в проблеме в дизассемблере при выполнении по одной команде и слать минимальный пример разработчику, пусть разбирается. Если будут дополнительные замечания и наблюдения, что идёт не так, они ещё и поощрить могут. Раз у Студии от MS вопросов нет, пусть остальные подтягиваются  Если С++ допустим, можно на его коде то же самое попробовать. Если будет падать -- ссылки на структуру заюзать. Всё же некрасиво наблюдать memcpy() в обменах структурированными данными.
|
|
|
|
|
Oct 20 2014, 14:07
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Цитата(_pv @ Oct 20 2014, 18:25)  а что там с #pragma pack, #pragma align и реальным размером im_int? Никак. Ничего принудительно не ставил. Проверил на другой тестовой структуре с таким же полем, но поменьше - все работает. С включенной оптимизацией кода тоже все работает. Вот дисассемблер нерабочего кода Красный брекпойн - начало копирования структур. Потом выделен последняя "рабочая" команда. Дальше программа уходит в какое-то исключение
Сообщение отредактировал kolobochishe - Oct 20 2014, 14:08
Эскизы прикрепленных изображений
|
|
|
|
|
Oct 31 2014, 10:10
|
Знающий
   
Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748

|
Цитата(kolobochishe @ Oct 20 2014, 14:41)  Структура типа im_rect является вложенной в структуре im_widget. на вскидку: невыровненная структура - вероятно в эксепшен вылетает смотрите чтобы все поля по 32 бита были. ну а если нет такой возможности - делайте юнион на свою структуру и копируйте с помощью memcpy по-байтно Не надо цитировать всё подряд.
Сообщение отредактировал Herz - Oct 31 2014, 15:32
Причина редактирования: Избыточное цитирование
|
|
|
|
|
Oct 31 2014, 12:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(inventor @ Oct 31 2014, 12:10)  на_вскидку: невыровненная структура - вероятно в эксепшен вылетает Автор пишет, что никаких специальных мер по нарушению выравнивания не предпринимал, читайте внимательнее. Цитата(inventor @ Oct 31 2014, 12:10)  смотрите чтобы все поля по 32 бита были. А это еще зачем? А вложенная стрктура тоже полем является, она тоже по 32 бита должна быть? Цитата(inventor @ Oct 31 2014, 12:10)  ну а если нет такой возможности - делайте юнион на свою структуру и копируйте с помощью memcpy по-байтно 1) у memcpy параметр имеет тип void *, согласно правилам неявного приведения типов указатель на структуру будет приведен к этому типу неявно. Никакой union не нужен. 2) Стандарт языка гарантирует, что структура должна копироваться без всяких плясок с бубном. Вне зависимости от размера, типа и количества своих членов. Даже если структура объявлена с другим выравниванием, компилятор об этом знает и обязан выполнять копирование корректно. Проблема с выравниванием может возникнуть только при доступе через указатель, если программист явным приведением типов сознательно нарушил правила выравнивания.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 1 2014, 08:35
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(Сергей Борщ @ Oct 31 2014, 18:56)  Автор пишет, что никаких специальных мер по нарушению выравнивания не предпринимал, читайте внимательнее.
Даже если структура объявлена с другим выравниванием, компилятор об этом знает и обязан выполнять копирование корректно. он хоть и обязан, но баги в компиляторах тоже бывают, и про VDSP нельзя сказать что это самый безглючный компилятор. тут похоже грабли из-за массива структур, посмотрите по каким именно адресам он от положил wFKey[0] и wFKey[1]. и для проверки, попробуйте добавить, сколько надо ucharов в структуру, чтобы размер sizeof(im_widget) стал кратным четырём.
|
|
|
|
|
Nov 1 2014, 10:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(_pv @ Nov 1 2014, 10:35)  попробуйте добавить, сколько надо ucharов в структуру, чтобы размер sizeof(im_widget) стал кратным четырём. Вот если размер im_widget окажется не равен четырем - это, действительно, будет бага компилятора. Потому что размер структуры по стандарту кратен наибольшему выравниванию ее членов. В структуре есть указатели, выравнивание указателя в VDSP, насколько понимаю, равно четырем - компилятор обязан размер структуры сделать кратным четырем. Очень сомневаюсь, что такую ошибку пропустили бы.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|