|
Вопрос на счет выравнивания переменных |
|
|
|
Oct 19 2009, 15:05
|

Частый гость
 
Группа: Участник
Сообщений: 98
Регистрация: 3-03-09
Пользователь №: 45 590

|
Всем привет! Код u32 func(char * array, u32 * A) { *A = 2; return *A; } Иногда возникает такая проблема, если А не выравнена по слову, попадает смещенная величина. Вот пример: В самом начале: ____word___________wordA____ | 00 00 00 00 |____| 00 00 00 00 | Должно получиться после присваивания: ____word___________wordA____ | 00 00 00 00 |____| 02 00 00 00 | А получается так: ____word___________wordA____ | 00 00 00 02 |____| 00 00 00 00 | Кто как борет это? Компилятор GCC.
Сообщение отредактировал AirDevil - Oct 19 2009, 15:06
|
|
|
|
|
Oct 19 2009, 17:05
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(AirDevil @ Oct 19 2009, 18:05)  Кто как борет это? Первое и самое главное не писать "говнокод" работу которого компилятор не сможет проконтролировать. Второе, если уж где-то реально нужно, то контролировать полученный адрес на выравненность и использовать для таких случаев (или тупо всегда) копирование областей памяти. Цитата(demiurg_spb @ Oct 19 2009, 18:28)  Для какой архитектуры компилятор? ARM, например. Не AVR, не x86....
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 19 2009, 19:27
|

Частый гость
 
Группа: Участник
Сообщений: 98
Регистрация: 3-03-09
Пользователь №: 45 590

|
Цитата(zltigo @ Oct 19 2009, 20:05)  Первое и самое главное не писать "говнокод" работу которого компилятор не сможет проконтролировать. Трудно не согласиться. Цитата(zltigo @ Oct 19 2009, 20:05)  Второе, если уж где-то реально нужно, то контролировать полученный адрес на выравненность и использовать для таких случаев (или тупо всегда) копирование областей памяти. В принципе и делал когда глюки были. Выравнивание с помощью memcpy и всё. Я думал, что возможно еще есть пути. Оказывается, что нет и вижу что делал правильно. С П А С И Б О ! ! !
Сообщение отредактировал AirDevil - Oct 19 2009, 19:29
|
|
|
|
|
Oct 19 2009, 20:13
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(AHTOXA @ Oct 19 2009, 22:44)  при условии, что A - это указатель на u32 Да, это указатель на u32, но не выровненный, а находящийся, например, в каком-нибудь буфере передачи.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 19 2009, 20:40
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(zltigo @ Oct 20 2009, 02:13)  Да, это указатель на u32, но не выровненный, а находящийся, например, в каком-нибудь буфере передачи. Для этого в IARе нужно было всего-то объявить невыравненный тип u32_unalign и вообще не напрягаться Код #pragma pack(push, 1) typedef u32 u32_unalign; #pragma pack(pop)
u32 func(u08 * array, u32_unalign * A) { u32 tmp = *(u32_unalign *)array; *A = tmp; return tmp; } Работает ли это в GCC ? Ессно изменив прагму.
Сообщение отредактировал GetSmart - Oct 19 2009, 21:17
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Oct 19 2009, 21:04
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(GetSmart @ Oct 19 2009, 23:40)  Работает ли это в GCC ? Ессно изменив прагму. Например: Код typedef unsigned int u32_unalign __attribute__ ((aligned (1))); Все-же атрибуты веселее прагм в большинстве случаев.
|
|
|
|
|
Oct 19 2009, 21:43
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(GetSmart @ Oct 19 2009, 23:40)  Для этого.. #pragma pack(push, 1) typedef u32 u32_unalign; #pragma pack(pop) Цитата(_Pasha @ Oct 20 2009, 00:04)  Например: typedef unsigned int u32_unalign __attribute__ ((aligned (1))); Даже не знаю, сметься, плакать, или спросить где Вы оба берете такую траву? Можно я помолчу?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 19 2009, 22:43
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
От зараза, не сработала  Я обычно через структуру или union работаю (в IARе), а тут решил "сэкономить" и даже не проверил. Код #pragma pack(push, 1) typedef union { float f; u32 l; u16 w[2]; u08 b[4]; } u32_unalign; #pragma pack(pop) Звиняюсь, за спешку. Но этот вариант уже точно правильно работает и при записи и при чтении невыравненных переменных (long/short/float). Хотя вопрос к тем, кто знает - почему "typedef u32 u32_unalign;" внутри прагмы не работает?
Сообщение отредактировал GetSmart - Oct 19 2009, 22:56
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Oct 19 2009, 23:54
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(GetSmart @ Oct 20 2009, 04:43)  Хотя вопрос к тем, кто знает - почему "typedef u32 u32_unalign;" внутри прагмы не работает? Потому что Цитата("IAR C/C++ Development Guide Compiling and linking for Advanced RISC Machines Ltd’s ARM® Core") Pragma directive | Description ------------------------------------------------------------------------------- pack | Specifies the alignment of structures and union members А отдельные переменные и так всегда выровнены.
|
|
|
|
|
Oct 20 2009, 00:32
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(GetSmart @ Oct 20 2009, 06:21)  Вполне "законно" можно передать туда адрес переменной u32, находящейся в структуре с невыравненными переменными. Кто так поступает, тот сам себе "злобный буратино". А если уж приспичило, то передавать нужно char-овский указатель, а не long-овский и копировать побайтово. Собственно все то же самое, что делает memcpy, с которой у топикстартера все нормально работает. Цитата(AirDevil @ Oct 20 2009, 01:27)  В принципе и делал когда глюки были. Выравнивание с помощью memcpy и всё. Я думал, что возможно еще есть пути. Оказывается, что нет и вижу что делал правильно.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|