|
|
  |
Приведение типа указателя на элемент структуры |
|
|
|
Oct 18 2012, 07:49
|

фанат дивана
     
Группа: Свой
Сообщений: 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, как я не извращался  Единственный вариант, который изменил размер, был вот такой: Код typedef struct { unsigned char a __attribute__ ((aligned (8))); unsigned char b __attribute__ ((aligned (8))); }str; Но этот вариант не страшен, потому что явно указывать alignment там, где он не нужен, мы не будем. Цитата(_Pasha @ Oct 18 2012, 13:44)  Дык я это "не то не к тому" унаследовал, пытаясь сказать, что сабжевое приведение - лишняя суета и потенциальный источник проблем. А, вон оно что! Теперь понял
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 18 2012, 08:23
|
Гуру
     
Группа: Свой
Сообщений: 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 };
|
|
|
|
|
Oct 18 2012, 08:45
|

фанат дивана
     
Группа: Свой
Сообщений: 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-ом)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 18 2012, 12:23
|

Профессионал
    
Группа: Свой
Сообщений: 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 получились РАЗНЫЕ, хотя этого вряд-ли кто-то добивался :-) Короче, плохая это прагма, не ленитесь писать атрибуты для каждой структуры.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Oct 18 2012, 14:47
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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 не помогут.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 18 2012, 15:51
|
Гуру
     
Группа: Свой
Сообщений: 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; нормально работало всегда и везде? или так лучше вообще не делать, а данные просто макросами по байтам по смещениям вытаскивать чтобы ни от платформы ни от компилятора не зависеть?
|
|
|
|
|
Oct 19 2012, 04:41
|

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

|
Цитата(AHTOXA @ Oct 18 2012, 19:20)  Можно безбоязненно пользоваться структурами от ST? Если программируем аппаратные средства микроконтроллеров STM32xxx, то используются не структуры, а указатели на типы структур, расположенные по фиксированным адресам. Если просто пользуемся структурами, подобными предложенным ST, то не все ли равно, как упакованы данные? Куда записали, оттуда и прочитаем.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|