Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ошибка при копировании структур
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
kolobochishe
Структура типа 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; // Работает


Т.е. виснет при копировании вложенных структур внутри массива.
WitFed
Думаю, надо точно убедиться в проблеме в дизассемблере при выполнении по одной команде и слать минимальный пример разработчику, пусть разбирается. Если будут дополнительные замечания и наблюдения, что идёт не так, они ещё и поощрить могут.
Раз у Студии от MS вопросов нет, пусть остальные подтягиваются wink.gif
Если С++ допустим, можно на его коде то же самое попробовать. Если будет падать -- ссылки на структуру заюзать. Всё же некрасиво наблюдать memcpy() в обменах структурированными данными.
_pv
а что там с #pragma pack, #pragma align и реальным размером im_int?
kolobochishe
Цитата(_pv @ Oct 20 2014, 18:25) *
а что там с #pragma pack, #pragma align и реальным размером im_int?


Никак. Ничего принудительно не ставил. Проверил на другой тестовой структуре с таким же полем, но поменьше - все работает. С включенной оптимизацией кода тоже все работает.

Вот дисассемблер нерабочего кода

Красный брекпойн - начало копирования структур. Потом выделен последняя "рабочая" команда. Дальше программа уходит в какое-то исключение
_pv
судя по P1.L = 0x8f1E, последующим за этим P1 += 4; и попытке достать потом по адресу 0x8f22 32х разрядное число, исключение в которое дальше всё уходит - misaligned access.
kolobochishe
Цитата(_pv @ Oct 20 2014, 21:44) *
судя по P1.L = 0x8f1E, последующим за этим P1 += 4; и попытке достать потом по адресу 0x8f22 32х разрядное число, исключение в которое дальше всё уходит - misaligned access.


А как Вы определили, что это именно "невыровненный доступ"?
_pv
P1=0x8f22 на 4 не делится, и R0 = [P1++] пытается достать 32х разрядные данные.
Xenia
А вы попробуйте без typedef:
Код
struct im_rect { im_int Left; im_int Top; im_int Right; im_int Bottom; };

struct im_widget {
  im_int Type;
  struct im_rect OuterRect;    
  struct im_rect InnerRect;
  .....
} wFKey[4];

Может, компилятору так больше понравится?
Я сама всегда так пишу, а без typedef только однажды обойтись не смогла.
inventor
Цитата(kolobochishe @ Oct 20 2014, 14:41) *
Структура типа im_rect является вложенной в структуре im_widget.


на вскидку: невыровненная структура - вероятно в эксепшен вылетает
смотрите чтобы все поля по 32 бита были.
ну а если нет такой возможности - делайте юнион
на свою структуру и копируйте с помощью memcpy по-байтно

Не надо цитировать всё подряд.
Сергей Борщ
Цитата(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) Стандарт языка гарантирует, что структура должна копироваться без всяких плясок с бубном. Вне зависимости от размера, типа и количества своих членов. Даже если структура объявлена с другим выравниванием, компилятор об этом знает и обязан выполнять копирование корректно. Проблема с выравниванием может возникнуть только при доступе через указатель, если программист явным приведением типов сознательно нарушил правила выравнивания.
_pv
Цитата(Сергей Борщ @ Oct 31 2014, 18:56) *
Автор пишет, что никаких специальных мер по нарушению выравнивания не предпринимал, читайте внимательнее.

Даже если структура объявлена с другим выравниванием, компилятор об этом знает и обязан выполнять копирование корректно.

он хоть и обязан, но баги в компиляторах тоже бывают, и про VDSP нельзя сказать что это самый безглючный компилятор.
тут похоже грабли из-за массива структур, посмотрите по каким именно адресам он от положил wFKey[0] и wFKey[1].
и для проверки, попробуйте добавить, сколько надо ucharов в структуру, чтобы размер sizeof(im_widget) стал кратным четырём.
Сергей Борщ
Цитата(_pv @ Nov 1 2014, 10:35) *
попробуйте добавить, сколько надо ucharов в структуру, чтобы размер sizeof(im_widget) стал кратным четырём.
Вот если размер im_widget окажется не равен четырем - это, действительно, будет бага компилятора. Потому что размер структуры по стандарту кратен наибольшему выравниванию ее членов. В структуре есть указатели, выравнивание указателя в VDSP, насколько понимаю, равно четырем - компилятор обязан размер структуры сделать кратным четырем. Очень сомневаюсь, что такую ошибку пропустили бы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.