Cianid 0 Posted August 26, 2021 (edited) · Report post Добрый день. Увидел разницу в работе атрибута у разных компиляторов. typedef struct __attribute__((packed)) { uint8_t a; uint8_t b; uint8_t c; float d; } str; gcc сразу упаковал в 7 байт. MinGW в 8 байт, т.е. ему пришлось принудительно указать выравнивание по 1 байту. Собственно где то можно подсмотреть по каким границам gcc выравнивает данные по умолчанию? Edited August 26, 2021 by Cianid Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted August 27, 2021 · Report post А MinGW - это не GCC? Вообще, без атрибута выравнивания на 32-разрядных платформах между с и d будет padding в один байт, т.к. на этих платформах эффективный 32-разрядный доступ должен быть выровненным, поэтому d будет выравниваться на границу 32-разрядного слова. Атрибуты (прагмы) упаковки могут менять поведение, но это расширения языка, тут общего стандарта (как и синтаксиса) нет. В ряде случаев у packed ещё можно (нужно) указывать число, определяющее кратность адреса для выравнивания. И обычно атрибут выравнивания указывают для объекта, а не для типа. Возможно тут "собака порылась". Quote Ответить с цитированием Share this post Link to post Share on other sites
Cianid 0 Posted August 27, 2021 (edited) · Report post 3 часа назад, dxp сказал: А MinGW - это не GCC? Вообще, без атрибута выравнивания на 32-разрядных платформах между с и d будет padding в один байт, т.к. на этих платформах эффективный 32-разрядный доступ должен быть выровненным, поэтому d будет выравниваться на границу 32-разрядного слова. Атрибуты (прагмы) упаковки могут менять поведение, но это расширения языка, тут общего стандарта (как и синтаксиса) нет. В ряде случаев у packed ещё можно (нужно) указывать число, определяющее кратность адреса для выравнивания. И обычно атрибут выравнивания указывают для объекта, а не для типа. Возможно тут "собака порылась". Не так выразился, не разные компиляторы. Я сравнивал arm и windows компиляторы. Ну вот и получилось, что для minGW пришлось дописывать #pragma pack(push,1). Edited August 27, 2021 by Cianid Quote Ответить с цитированием Share this post Link to post Share on other sites
Сергей Борщ 0 Posted August 27, 2021 · Report post Похоже, тут корни тянутся от M$-компиляторов, которые как всегда сделали не как у людей и поведение которых mingw по каким-то причинам пародирует: https://gcc.gnu.org/onlinedocs/gcc/x86-Type-Attributes.html Quote Ответить с цитированием Share this post Link to post Share on other sites
dimka76 0 Posted August 27, 2021 · Report post 1 hour ago, Cianid said: Не так выразился, не разные компиляторы. Я сравнивал arm и windows компиляторы. Хорошо бы было изъясняться более понятно, чтобы получить правильный ответ на ваш вопрос. В MinGW атрибут __attribute__((packed)) игнорируется. Вместо него следует применять #pragma pack. Quote Ответить с цитированием Share this post Link to post Share on other sites
Сергей Борщ 0 Posted August 27, 2021 · Report post 11 минут назад, dimka76 сказал: В MinGW атрибут __attribute__((packed)) игнорируется. Можно ссылку на документацию? Компилю для виндовс свои простенькие програмки под линухом при помощи i686-w64-mingw32-gcc, #pragma pack не использую, использую __attribute__((packed)) и -mno-ms-bitfields, програмки работают одинаково под линухом и виндовсом. Quote Ответить с цитированием Share this post Link to post Share on other sites
dimka76 0 Posted August 27, 2021 · Report post 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 Quote Ответить с цитированием Share this post Link to post Share on other sites
Cianid 0 Posted August 27, 2021 · Report post 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, если хочется меньше головной боли. Quote Ответить с цитированием Share this post Link to post Share on other sites
dimka76 0 Posted August 27, 2021 · Report post На работе тоже микроконтроллер 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; Никаких специальных ключей компилятора для упаковки структур не применяются. И все всегда работает. Quote Ответить с цитированием Share this post Link to post Share on other sites
Cianid 0 Posted August 27, 2021 · Report post Ну вот ровно так же я и сделал. Quote Ответить с цитированием Share this post Link to post Share on other sites