реклама на сайте
подробности

 
 
6 страниц V  « < 2 3 4 5 6 >  
Reply to this topicStart new topic
> Приведение типа указателя на элемент структуры
AHTOXA
сообщение Oct 18 2012, 07:49
Сообщение #46


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MrYuran @ Oct 18 2012, 12:25) *
Я не знаю, что надо сделать, но точно знаю теперь, чего не надо..
Не надо использовать такие структуры без принудительной упаковки, во избежание.
Мне совершенно было не смешно, когда port1.out.pin3 = 1 махал битами в регистре dir вместо out (а это ещё надо было найти)
Скорее всего был локальный глюк какой-то конкретной версии mspgcc. Хотя принудительная упаковка - дело несложное, можно и её добавить, для пущей уверенности.

Цитата(Палыч @ Oct 18 2012, 12:55) *
Вставить #pragma pack(n) или указать транслятору -fpack-struct=n cо значением n отличным от 1.
К сожалению, в документации на gcc нигде нет упоминания: какое значение n (величина выравнивания) принято "по-умолчанию"...

Нет, ничего из этого не увеличивает размер структуры. Проверил и с #pragma pack(x), и с -fpack-struct=x (x={4,8,16,32}), и с ними обоими одновременно.
До кучи проверил __attribute__ ((packed)) и __attribute__ ((aligned (x))) для типа.
Размер структуры равен 2, как я не извращался sm.gif
Единственный вариант, который изменил размер, был вот такой:
Код
typedef struct
{
    unsigned char a __attribute__ ((aligned (8)));
    unsigned char b __attribute__ ((aligned (8)));
}str;

Но этот вариант не страшен, потому что явно указывать alignment там, где он не нужен, мы не будем.

Цитата(_Pasha @ Oct 18 2012, 13:44) *
Дык я это "не то не к тому" унаследовал, пытаясь сказать, что сабжевое приведение - лишняя суета и потенциальный источник проблем.

А, вон оно что! Теперь понялsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 18 2012, 07:54
Сообщение #47


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Oct 18 2012, 10:44) *
Ну не может быть, чтобы хаки и нормальные построения вели себя везде одинаково!

Приведение типов - не хак. А осознанная необходимость. Я не с дырами борюсь, их у меня нет. А хочу писать не только 8-битовыми словами, но и 16-битовыми, 32-битовыми. Cortex-M это позволяет делать, начиная с любого адреса. Тем более, регистры микроконтроллера (или контроллера ЖКИ, который использую) и так выровнены по адресам.
Приведение типов указателя - обычное дело.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2012, 08:16
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(AHTOXA @ Oct 18 2012, 11:49) *
Нет, ничего из этого не увеличивает размер структуры.
А теперь попробуйте проверить на такой структуре:
Код
typedef struct
{
    unsigned char a;
    unsigned int  b;
    unsigned char c;
}str;
Go to the top of the page
 
+Quote Post
XVR
сообщение Oct 18 2012, 08:23
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Вообще то компиляторы упаковывают структуры не от их [компилятора] большого желания, а от требования выполнить ограничения по выравниванию для полей этих самых структур. Так что, если у вас в структуре нет полей с требованиями по выравниванию (например у вас там все char) - то ничего выравниваться и не будет. А вот если есть - то перед этим полем может появится дыра, и вся структура в целом получит ограничение по выравниванию, как для этого поля (что в свою очередь может добавить дыру и в конце структуры)
Например (предполагаю требования по выравниванию на размер поля):
Код
struct {
int8_t f8;
int16_t f16;
int32_t f32;
int8_t  f8_2;
};
// Превратится в
struct {
int8_t f8;
int   :8; // Выравнивание для f16 на границу 2х байтов
int16_t f16;
int  :16; // Выравнивание для f32 на границу 4х байтов
int32_t f32;
int8_t f8_2;
int :24; // Выравнивание размера всей структуры, как требует поле f32
};
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 18 2012, 08:27
Сообщение #50


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(XVR @ Oct 18 2012, 11:23) *
int :16; // Выравнивание для f32 на границу 4х байтов

лишнее
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 18 2012, 08:43
Сообщение #51


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Oct 18 2012, 10:54) *
Приведение типов - не хак. А осознанная необходимость.
***
Cortex-M это позволяет делать, начиная с любого адреса.

biggrin.gif А сколько воплей у народа по поводу невыровненного доступа на AT91** например! Там не особо позволяет 7tdmi.

Цитата(ViKo @ Oct 18 2012, 11:27) *
лишнее

Оно уже для другого: читаем программу и если чего-то надо добавить, сразу видим, сколько бит осталось.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 08:45
Сообщение #52


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Палыч @ Oct 18 2012, 14:16) *
А теперь попробуйте проверить на такой структуре:

Да, но речь шла о структурах, уже имеющих вручную сформированные отступы, типа такой:
Код
typedef struct
{
    uint8_t a;
    uint8_t padder1;    // - отступ
    uint16_t b;
    uint16_t padder2;  // - отступ
    uint32_t c;
}str;

Такие структуры используются, в частности, в заголовочных файлах от ST для описания периферии процессоров STM32. И меня интересует вопрос, могут ли такие структуры при каких-либо условиях перестать соответствовать описываемой ими периферии.
Пока получается, что всё нормально, соответствуют при любых ключах компиляции. (Ну, кроме непонятного случая, описанного MrYuran-ом)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
XVR
сообщение Oct 18 2012, 08:47
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(ViKo @ Oct 18 2012, 12:27) *
лишнее
Да, точно. Просчитался laughing.gif
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 18 2012, 12:23
Сообщение #54


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(Палыч @ Oct 18 2012, 10:55) *
Вставить #pragma pack(n) или указать транслятору -fpack-struct=n cо значением n отличным от 1.


Раз тут пошли "страшные истории"...
pragma pack(n) надо обязательно закрывать pragma pack()
При включении заголовка с незакрытой прагмой такие интересные косяки проявляются - все структуры в одном модуле сами собой "упаковываются", а в другом - остаются неупакованными, в зависимости от последовательности #include.

Пример для наглядности:
Код
a.h:
#pragma pack (1)

b.h
typedef struct .... b_struct;

a.c
#include "a.h"
#include "b.h"
b_struct A;

b.h
#include "b.h"
b_struct B;


Так вот, A и B получились РАЗНЫЕ, хотя этого вряд-ли кто-то добивался :-)
Короче, плохая это прагма, не ленитесь писать атрибуты для каждой структуры.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 18 2012, 14:47
Сообщение #55


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(AHTOXA @ Oct 18 2012, 11:45) *
Пока получается, что всё нормально, соответствуют при любых ключах компиляции. (Ну, кроме непонятного случая, описанного MrYuran-ом)
Там, я так понял, ещё битовые поля были в подструктурах ioregister_t.
Что-то могло и на этом набежать.
Скажем,
Код
typedef {
    unsigned f : 1;
} flag_t;

typedef {
    flag_t a;
    flag_t b;
} flags2_t;
структура flags2_t займёт 2*sizeof(unsigned), а не один байт. Причём никакие pack не помогут.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_pv
сообщение Oct 18 2012, 15:51
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(esaulenka @ Oct 18 2012, 19:23) *
Короче, плохая это прагма, не ленитесь писать атрибуты для каждой структуры

а если есть некая структура
Код
typedef struct{
  u8 b;
  u32 c;  
  u8 d;
  u16 a;  
} t_struct_A;


и указатель
Код
t_struct_A * p;

который еще потом может вдруг оказаться совсем невыровненным, ну там преамбула например частично потерялась:
Код
u8 buff[100500];
p = &buff[17];

в каком именно месте и какие прагмы должны стоять чтобы p->c = 0xABCD1234; нормально работало всегда и везде?
или так лучше вообще не делать, а данные просто макросами по байтам по смещениям вытаскивать чтобы ни от платформы ни от компилятора не зависеть?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 18 2012, 16:20
Сообщение #57


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ReAl @ Oct 18 2012, 20:47) *
Там, я так понял, ещё битовые поля были в подструктурах ioregister_t.
Что-то могло и на этом набежать.

Наверное.
Ну а в результате, какой будет вывод? Можно безбоязненно пользоваться структурами от ST? Или ждать, когда _Pasha сделает базу данных? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 19 2012, 04:41
Сообщение #58


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 18 2012, 19:20) *
Можно безбоязненно пользоваться структурами от ST?

Если программируем аппаратные средства микроконтроллеров STM32xxx, то используются не структуры, а указатели на типы структур, расположенные по фиксированным адресам.
Если просто пользуемся структурами, подобными предложенным ST, то не все ли равно, как упакованы данные? Куда записали, оттуда и прочитаем.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 19 2012, 04:59
Сообщение #59


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ViKo @ Oct 19 2012, 10:41) *
Если программируем аппаратные средства микроконтроллеров STM32xxx, то используются не структуры, а указатели на типы структур, расположенные по фиксированным адресам.

Какая нафиг разница? Если структура вдруг разъедется, то мы промахнёмся мимо нужного регистра и по указателюsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 19 2012, 05:49
Сообщение #60


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Oct 19 2012, 07:59) *
Какая нафиг разница? Если структура вдруг разъедется, то мы промахнёмся мимо нужного регистра и по указателюsm.gif

Как же она разъедется, если указателю передан конкретный адрес! А дыры зарезервированы неиспользуемыми переменными.
P.S. Мы же ее (структуру) уже разъехали разъездили раскатали растянули.
Go to the top of the page
 
+Quote Post

6 страниц V  « < 2 3 4 5 6 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.0152 секунд с 7
ELECTRONIX ©2004-2016