Перейти к содержанию
    

Выравнивание данных в структуре

Товарищи,

есть в программе структура типа такой:

typedef struct {                                                                                          
uint8_t  Cnt;                                                                                               
float    Len;                                                                                           
float    Depth;                                                                                          
uint8_t  Roll;                                                                                            
float    Pitch;                                                                                            
uint8_t  Hours;                                                                                            
uint8_t  Minutes;                                                                                          
uint8_t  Day;                                                                                              
uint8_t  Month;                                                                                            
uint8_t  Year;                                                                                             
} LOG_Type;  

Если посчитать, то получается размер 19 байт. Но если использовать sizeof(LOG_Type), то получается 28 байт. 

Посмотрел в памяти и увидел, что компилятор все float'ы выровнял по границе 4 байт.

А мне эту структуру надо отправлять по SPI побайтно и все эти лишние нули мне совсем не нужны.

Как быть ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, TOG said:

Как быть ?

Почитайте про "__attribute__((packed))", пример:

struct __attribute__((packed)) T_UINT32 { uint32_t v; };

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, Arlleex said:

Ну, поехали🙂

да пускай чуток по-страдает, все через это проходят ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

32 минуты назад, TOG сказал:

А мне эту структуру надо отправлять по SPI побайтно и все эти лишние нули мне совсем не нужны.

Как быть ?

Т.е. - за 17 лет пребывания на этом форуме вы не видели здесь не одной темы про выравнивание и упаковку? Коих только за последнее время было несколько.

И учебник по си не открывали ни разу? И не читали в нём ничего про выравнивание и про структуры вообще?

ЗЫ: В таком случае уже ничего не сделаешь.... :unknw:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/10/2023 at 12:53 PM, Forger said:

Почитайте про "__attribute__((packed))", пример:

Сделал. Спасибо, Forger !

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 часов назад, unix сказал:

Также, если указатель на такую структуру объявлять, тоже надо указывать packed 

Это как и зачем?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 hours ago, unix said:

Также, если указатель на такую структуру объявлять, тоже надо указывать packed

нет, это бессмысленно, т.к. компилятор и так прекрасно знает с какой структурой работает, а если не знает, то просто будет ошибка компиляции

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/10/2023 at 11:17 AM, Arlleex said:

Ну, поехали🙂

:dance3:

 

On 11/10/2023 at 10:48 AM, TOG said:

Товарищи,

есть в программе структура типа такой:

typedef struct {                                                                                          
uint8_t  Cnt;                                                                                               
float    Len;                                                                                           
float    Depth;                                                                                          
uint8_t  Roll;                                                                                            
float    Pitch;                                                                                            
uint8_t  Hours;                                                                                            
uint8_t  Minutes;                                                                                          
uint8_t  Day;                                                                                              
uint8_t  Month;                                                                                            
uint8_t  Year;                                                                                             
} LOG_Type;  

Если посчитать, то получается размер 19 байт. Но если использовать sizeof(LOG_Type), то получается 28 байт. 

Посмотрел в памяти и увидел, что компилятор все float'ы выровнял по границе 4 байт.

А мне эту структуру надо отправлять по SPI побайтно и все эти лишние нули мне совсем не нужны.

Как быть ?

 

уже сломано копий немеряно. будут советы по атрибуту packed.  я делаю так. разбираем структуру руками поэлементно. если есть что- то длиннее char, затаскиваю в специально созданный union  в котором будет 2 short int  1 float и 4 char  и оттуда каждый элемент побайтно вытаскиваем. громоздко, но вы никогда не будете размышлять: что и куда у вас попадет. как разновидность, можно указателю на char присваивать указатель на очередной длинный объект и по элементу вытаскивать. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

37 minutes ago, firstvald said:

я делаю так. разбираем структуру руками поэлементно

порой это невозможно и порядок полей определен извне кем-то и приходится работать с тем что есть 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, firstvald сказал:

разбираем структуру руками поэлементно. если есть что- то длиннее char, затаскиваю в специально созданный union  в котором будет 2 short int  1 float и 4 char  и оттуда каждый элемент побайтно вытаскиваем. громоздко, но вы никогда не будете размышлять: что и куда у вас попадет.

Ну да - в таком буреломе на пустом месте, больше размышлять придётся ища баги. Не до попаданий будет. И ещё не забывая всё это безобразие перепахивать по новой при малейшем изменении структуры.
Зачем ваять лисапед с треугольными колёсами, вместо того чтобы воспользоваться штатными возможностями компилятора??
Вы и 32-разрядные числа тоже поразрядно складываете? Снимая элемент случайности.  :crazy:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, jcxz сказал:

... это безобразие перепахивать по новой при малейшем изменении структуры.

Этого не избежать когда определён "сетевой порядок следования" байт, не совпадающий с порядком в МК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, Палыч сказал:

Этого не избежать когда определён "сетевой порядок следования" байт, не совпадающий с порядком в МК.

А при чём тут...? Вроде разговор был про "выравнивание членов структуры", а не про "порядок байт".

Да и со сменой порядка байт тоже можно сделать нормально, а не через одно место:
Во первых - можно такие типы данных определить как объекты классов. И перегрузить их операторы присвоения или операторы приведения типа к стандартным типам. В которых и сделать смену порядка байт.
Во-вторых - например в ARM имеются специальные команды изменения порядка байт в слове.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...