|
|
  |
Приведение типа указателя на элемент структуры |
|
|
|
Oct 19 2012, 09:27
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(AHTOXA @ Oct 19 2012, 10:31)  Так вот я и выясняю, не может ли она после этого разъехаться ещё больше  Представьте, что есть ключ компилятора, который каждый байт в структуре выравнивает на границу слова. С таким ключом всё наше растягивание пойдёт насмарку. Самое простое - не морочить, а заложить где-то assert, только вот что лучше проверять: небось, sizeof какой-то тестовой структуры, не обязательно прям-таки осмысленной и привязанной к реальным портам, но с использованием всех индуистских _IO32 и прочая.
|
|
|
|
|
Oct 19 2012, 09:32
|

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

|
К счастью, в железе STM32 адреса устройств уже распределены так, что "упаковываются" в структурах согласно своему естественному размеру, int16_t по границам полуслова, int32_t по границам слова. Во всяком случае, я не заметил, чтобы где-то в stm32fxx.h было не так. Поэтому, если не насиловать компилятор прагмами pack(n), ничто расползаться не должно. А __packed может только утоптать структуру, но не раздвинуть ее. А от этого мы уже защитились RESERVED. Так, вроде?
|
|
|
|
|
Oct 19 2012, 09:57
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(ViKo @ Oct 19 2012, 12:32)  К счастью, в железе STM32 [...] В принципе, тут зацепились мы за платформенно-независимый вопрос. Цитата Поэтому, если не насиловать компилятор прагмами pack(n) ... а также приведением типов указателей на элемент структуры  ...
|
|
|
|
|
Oct 26 2012, 20:10
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(ViKo @ Oct 17 2012, 09:51)  Допустим, имеется структура из байтов. Хочу инициализировать сразу 2 байта 16-битовым числом, или сразу 4 байта 32-битовым числом. Привожу указатель к нужному типу Похоже, при формировании структуры си-компилятор находит элемент с максимальной длиной и выделяет каждому элементу структуры размер памяти, равный максимальной длине. По крайней мере, для кейловского компилятора я это доказал. Выделил структуру typedef struct { unsigned long VARA; unsigned char VARB; unsigned int VARC; } CRCSTRUCT; CRCSTRUCT STRD; и в дибаггере стал туда писать побайтно, начиная с VARА. В VARА записалось 4 байта, как и ожидалось, в VARВ записался один байт, остальные три писались в никуда и не отображались, в VARC записалось два байта, остальные записались в никуда. Так что дырки в структурах всегда будут, если структура содержит элементы разной длины.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Nov 9 2012, 18:48
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Есть Грабля! CODE typedef struct { char id[2]; uint32_t size; char reserved[4]; uint32_t offset; uint32_t bmp_infolen; uint32_t width; uint32_t height; uint16_t planes;//number of uint16_t bits_per_pix; uint32_t compress_type; uint32_t picture_size; uint32_t Hresolution; uint32_t Vresolution; uint32_t used_colors; uint32_t important_colors; } bmp_header_t; Компилим Код gcc версия 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) с дефолтными настройками code::blocks (уверяю, там ничего страшного нету, выравнивание нигде принудительно не включено) Пишет после bmp_header.id два нулевых байта, также при выводе его размера показывает 56 байт супротив 54-х. В общем, подарок для АНТОХИ.  ЗЫ причем, сгенеренный и исходный BMP отличаются ровно на этих 2 байта PPS добавили #pragma pack(1) - получили всё, что надо. 54 байта. Оттакот! ppps Что-то пользоваться таким ГЦЦ расхотелось...
Сообщение отредактировал _Pasha - Nov 9 2012, 19:11
|
|
|
|
|
Nov 9 2012, 19:29
|

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

|
QUOTE (_Pasha @ Nov 9 2012, 20:48)  CODE typedef struct { char id[2]; uint32_t size; И что же вы ожидали (надеюсь, это был не AVR или MSP430)?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 20 2013, 09:45
|

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

|
Всплыл вопрос, кажется, подойдет в эту тему. Создаю суперструктуру из нескольких разных структур. В каждой из структур переменные разного размера кидаю, как попало. Не знаю, создаются дыры или нет, но пока использовал структуры по-отдельности, проблем не было. Keil знает, куда положил, и откуда брать. Для Cortex-M нет проблем. В суперструктуре должно быть аналогично.
Теперь хочу копировать суперструктуру в другую, такую же (backup). Хочу делать это 32-битовыми пересылками. Кроме того, хочу вычислять аппаратно CRC суперструктуры, туда тоже нужно посылать 32-битовые слова. Задаю указателю на uint32 адрес суперструктуры (uint32_t *)&Ctrl. Вычисляю ее размер в словах (!) size(Ctrl_t) / 4. И так собираюсь использовать.
Вопросы: 1. Что гарантирует, что вся суперструктура разместится по выровненному до слова адресу? Что будет, если первый элемент - 8-битовый? 2. Как задать, чтобы ее размер был равен целому числу слов? Пока напихал несколько пустых байтов, каждая мелкая структура - по 2-4-8 байтов, общее количество 44 байта (но, может, есть и дыры двухбайтовые?). В конце суперструктуры задаю 32-битовую CRC, это гарантирует выравнивание по словам, и целое число слов?
|
|
|
|
|
Dec 20 2013, 11:05
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
QUOTE (ViKo @ Dec 20 2013, 11:45)  2. Как задать, чтобы ее размер был равен целому числу слов? Я точно не вспомню, но делал что то типа такого: Помещал "супер структуру" + массив байт в "супер-супер структуру" Размерность массива байт задавал как остаток от деления sizeof("супер структура") на 4. Единственное, что не могу вспомнить, как обходил ситуацию с нулевым размером массива байт.
|
|
|
|
|
Dec 20 2013, 11:08
|

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

|
Запустил компиляцию с опцией --remarks. Вижу: enum занимают по 32 бита! Неоправданная роскошь. К структуре с enum и 3-мя uint_16 добавилось... видимо 2 байта в конце. По структуре Ctrl никаких замечаний не увидел. Добавил uint8_t в конец Ctrl. Получил замечание, что добавило padding. Делаю вывод - ничего не бойся, не проси...  Сам Кейл придет и принесет.
|
|
|
|
|
Dec 20 2013, 11:14
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 24-11-07
Пользователь №: 32 633

|
Цитата(ViKo @ Dec 20 2013, 15:08)  enum занимают по 32 бита! Неоправданная роскошь. Каждый из элементов enum - это int. Так что если машинное слово 32-х разрядное, то всё верно.
--------------------
Если друг оказался вдруг и не друг и не враг, а - JTAG.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|