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

Выравнивание данных gcc и MinGW

Добрый день. Увидел разницу в работе атрибута у разных компиляторов.

typedef struct __attribute__((packed))
{
  uint8_t a;
  uint8_t b;
  uint8_t c;
  float d;
} str;

gcc сразу упаковал в 7 байт. MinGW в 8 байт, т.е. ему пришлось принудительно указать выравнивание по 1 байту.

Собственно где то можно подсмотреть по каким границам gcc выравнивает данные по умолчанию? 

Изменено пользователем Cianid

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


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

А MinGW - это не GCC?

 

Вообще, без атрибута выравнивания на 32-разрядных платформах между с и d будет padding в один байт, т.к. на этих платформах эффективный 32-разрядный доступ должен быть выровненным, поэтому d будет выравниваться на границу 32-разрядного слова. Атрибуты (прагмы) упаковки могут менять поведение, но это расширения языка, тут общего стандарта (как и синтаксиса) нет. В ряде случаев у packed ещё можно (нужно) указывать число, определяющее кратность адреса для выравнивания.

 

И обычно атрибут выравнивания указывают для объекта, а не для типа. Возможно тут "собака порылась".

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


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

3 часа назад, dxp сказал:

А MinGW - это не GCC?

 

Вообще, без атрибута выравнивания на 32-разрядных платформах между с и d будет padding в один байт, т.к. на этих платформах эффективный 32-разрядный доступ должен быть выровненным, поэтому d будет выравниваться на границу 32-разрядного слова. Атрибуты (прагмы) упаковки могут менять поведение, но это расширения языка, тут общего стандарта (как и синтаксиса) нет. В ряде случаев у packed ещё можно (нужно) указывать число, определяющее кратность адреса для выравнивания.

 

И обычно атрибут выравнивания указывают для объекта, а не для типа. Возможно тут "собака порылась".

Не так выразился, не разные компиляторы. Я сравнивал arm и windows компиляторы.

 

Ну вот и получилось, что для minGW пришлось дописывать #pragma pack(push,1).

Изменено пользователем Cianid

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


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

Похоже, тут корни тянутся от M$-компиляторов, которые как всегда сделали не как у людей и поведение которых mingw по каким-то причинам пародирует:

https://gcc.gnu.org/onlinedocs/gcc/x86-Type-Attributes.html

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


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

1 hour ago, Cianid said:

Не так выразился, не разные компиляторы. Я сравнивал arm и windows компиляторы.

Хорошо бы было изъясняться более понятно, чтобы получить правильный ответ на ваш вопрос.

В MinGW атрибут __attribute__((packed)) игнорируется. Вместо него следует применять #pragma pack.

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


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

11 минут назад, dimka76 сказал:

В MinGW атрибут __attribute__((packed)) игнорируется.

Можно ссылку на документацию? Компилю для виндовс свои простенькие програмки под линухом при помощи i686-w64-mingw32-gcc, #pragma pack не использую, использую __attribute__((packed)) и -mno-ms-bitfields, програмки работают одинаково под линухом и виндовсом.

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


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

15 minutes ago, Сергей Борщ said:

Можно ссылку на документацию? Компилю для виндовс свои простенькие програмки под линухом при помощи i686-w64-mingw32-gcc, #pragma pack не использую, использую __attribute__((packed)) и -mno-ms-bitfields, програмки работают одинаково под линухом и виндовсом.

Ссылку на документацию дать не могу. Нет у меня такой ссылки )))

Несколько лет назад сталкивались с такой же ситуацией для проектов на Qt.

А сейчас смог найти только такую ссылку

https://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw

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


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

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

Хорошо бы было изъясняться более понятно, чтобы получить правильный ответ на ваш вопрос.

В MinGW атрибут __attribute__((packed)) игнорируется. Вместо него следует применять #pragma pack.

Не совсем понимаю какой информации не хватает. Просто опишу контекст. Я c 1986ВЕ1Т по uart кидаю через union массив, который отображается на структуру. А принимаю уже через QT-minGW. И получилось что у меня в контроллере 33 байта занимает структура, а в Qt уже 38. Вот там и обернул прагмой на выравнивание по 1 байту.

1 час назад, Сергей Борщ сказал:

Похоже, тут корни тянутся от M$-компиляторов, которые как всегда сделали не как у людей и поведение которых mingw по каким-то причинам пародирует:

https://gcc.gnu.org/onlinedocs/gcc/x86-Type-Attributes.html

Забавно, пишут что Microsoft ABI МОЖЕТ упаковать отлично от gcc. В общем необходимо указывать атрибут gcc_struct, если хочется меньше головной боли.

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


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

На работе тоже микроконтроллер Cortex общается с компьютером и тоже в протоколе используем упакованные структуры.

Компилятор для Cortex  - arm-none-eabi-gcc

Компилятор для компа - Visual Studio.

И тот и другой компиляторы были разных годов выпуска (если можно так выразится).

Для микроконтроллера структуры описывались так

typedef struct
{
  // тут разные типы данных
}__attribute__((packed)) t_data;

t_data data_1;

Для компа так

#pragma pack(push, 1)

typedef struct {
	// .......
}t_data;

#pragma pack(pop)
  
t_data data_1;

Никаких специальных ключей компилятора для упаковки структур не применяются.

И все всегда работает.

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


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

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

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

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

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

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

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

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

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

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