| gcc, Выравнивание на 64-битных архитектурах | |
| От: | artem_korneev![]() | ||
| Дата: | 22.04.09 12:54 |
Столкнулся сегодня с одной проблемой. Есть структура данных, состоящая из нескольких полей — 64-битный float, потом 8 unsigned char и один Int32. Итого получается 20 байт (8 + 8*1 + 4). Под 32-битными системами sizeof равен 20 и всё работает нормально. А под 64-битным Linux'ом sizeof возвращает 24. Т.е. идёт выравнивание по границе 64 бит. Я пробовал добавлять в конец структуры директиву align:
Не помогает. Пока сделал маленький костыль, принудительно используя значение 20, вместо sizeof, но мне этот костыль не нравится, хочется сделать по-человечески. Что можно покурить для просветления? С уважением, Artem Korneev. |
| Теги: | gcc, amd64 |
| Re: gcc, Выравнивание на 64-битных архитектурах | |
| От: | ra88![]() | ||
| Дата: | 22.04.09 13:09 | ||
| Оценка: | 31 (2) +1 | ||
| Здравствуйте, artem_korneev, Вы писали: _>Столкнулся сегодня с одной проблемой. Есть структура данных, состоящая из нескольких полей — 64-битный float, потом 8 unsigned char и один Int32. Итого получается 20 байт (8 + 8*1 + 4). Под 32-битными системами sizeof равен 20 и всё работает нормально. А под 64-битным Linux'ом sizeof возвращает 24. Т.е. идёт выравнивание по границе 64 бит. Я пробовал добавлять в конец структуры директиву align: _>
_>Не помогает. _>Пока сделал маленький костыль, принудительно используя значение 20, вместо sizeof, но мне этот костыль не нравится, хочется сделать по-человечески. Что можно покурить для просветления? Попробуй
while true; |
| Re: gcc, Выравнивание на 64-битных архитектурах | |
| От: | Аноним 415 | ||
| Дата: | 22.04.09 13:30 | ||
| Оценка: | 29 (1) +1 | ||
| Здравствуйте, artem_korneev, Вы писали: _>Столкнулся сегодня с одной проблемой. Есть структура данных, состоящая из нескольких полей — 64-битный float, потом 8 unsigned char и один Int32. Итого получается 20 байт (8 + 8*1 + 4). Под 32-битными системами sizeof равен 20 и всё работает нормально. А под 64-битным Linux'ом sizeof возвращает 24. Т.е. идёт выравнивание по границе 64 бит. Я пробовал добавлять в конец структуры директиву align: aligned, а не align http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html#Type-Attributes а вообще вам надо:
|
| Re[2]: gcc, Выравнивание на 64-битных архитектурах | |
| От: | artem_korneev![]() | ||
| Дата: | 22.04.09 13:36 |
| Здравствуйте, ra88, Вы писали: R>Попробуй R>#pragma pack(4) Спасибо, помогло. Я удивлён, я думал, что #pragma pack это чисто майкрософтовское. Интересно, а будет ли это работать под другими компиляторами? Мне-то нужно поддерживать код для gcc, icc, visual studio, и ещё каких-то там. Надо попробовать. С уважением, Artem Korneev. |
| Re[3]: gcc, Выравнивание на 64-битных архитектурах | |
| От: | ra88![]() | ||
| Дата: | 22.04.09 13:46 |
| Здравствуйте, artem_korneev, Вы писали: _>Здравствуйте, ra88, Вы писали: R>>Попробуй R>>#pragma pack(4) _>Спасибо, помогло. Я удивлён, я думал, что #pragma pack это чисто майкрософтовское. _>Интересно, а будет ли это работать под другими компиляторами? Мне-то нужно поддерживать код для gcc, icc, visual studio, и ещё каких-то там. Надо попробовать. для "спасибо" кнопка есть по gcc: http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html#Structure_002dPacking-Pragmas остальные не знаю... while true; |
| Re: gcc, Выравнивание на 64-битных архитектурах | |
| От: | Erop![]() | ||
| Дата: | 22.04.09 18:07 |
| Здравствуйте, artem_korneev, Вы писали: _>
_>Что можно покурить для просветления? Прочти тут: http://www.rsdn.ru/Forum/message/1461439.aspx Автор: Erop , тогда я смогу понятно объяснить дальше.Дата: 28.10.05 __attribute__ ((align(4))) задаст выравнивание, с которым потом будет размещаться структура TEstStruct, а на то, с какими выравниваниями будут размещаться её поля влияет pragma pack. В целом pragma pack присутствует в том или ином виде во всех известных мне компиляторах... Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском |
| Re: gcc, Выравнивание на 64-битных архитектурах | |
| От: | Vain![]() | ||
| Дата: | 22.04.09 18:47 |
| Здравствуйте, artem_korneev, Вы писали: _>
_>Не помогает. Не пробовали __attribute__ указывать перед структурой, а не после? In theory there is no difference between theory and practice. In practice there is. http://esquire.ru/test-82 |
| Re: gcc, Выравнивание на 64-битных архитектурах | |
| От: | Pzz![]() | ||
| Дата: | 22.04.09 22:45 |
| Здравствуйте, artem_korneev, Вы писали: _>Не помогает. Если сделать массив из таких структур, то при размере структуры в 20 байт в каждой второй структуре float64 будет не выровнен. Чтобы этого избежать, gcc делает размер структуры кратным 8-и. Т.е., это выравнивание не между полями структуры, а после последнего поля. Про #pragma pack вам уже рассказали, повторяться не буду |
| Re[2]: gcc, Выравнивание на 64-битных архитектурах | |
| От: | artem_korneev![]() | ||
| Дата: | 25.04.09 17:29 |
| Здравствуйте, Erop, Вы писали: E>Прочти тут: http://www.rsdn.ru/Forum/message/1461439.aspx Автор: Erop , тогда я смогу понятно объяснить дальше.Дата: 28.10.05 Почитал. Спасибо, интересно. E>__attribute__ ((align(4))) задаст выравнивание, с которым потом будет размещаться структура TEstStruct, а на то, с какими выравниваниями будут размещаться её поля влияет pragma pack. В целом pragma pack присутствует в том или ином виде во всех известных мне компиляторах... Я посмотрел на список поддерживаемых в проекте компиляторов, помедитировал над ним и решил переписать код сериализации так, чтобы он работал с данными отдельно, по элементам, а не со структурой. Не очень здорово в плане структуры кода, но в этом случае проблем с выравниванием нет. Использование директив компиляторов в моём случае чревато тем, что я могу наткнуться на компилятор, не поддерживающий эти директивы и тогда я получу кучу труднодиагностируемых глюков. С уважением, Artem Korneev. |
| Re[3]: gcc, Выравнивание на 64-битных архитектурах | |
| От: | Erop![]() | ||
| Дата: | 25.04.09 19:28 |
| Здравствуйте, artem_korneev, Вы писали: _>Почитал. Спасибо, интересно. Всегда рад. _>...не поддерживающий эти директивы и тогда я получу кучу труднодиагностируемых глюков. В принципе можно StaticAssert какой-нибудь написать... Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском |
| Re[3]: gcc, Выравнивание на 64-битных архитектурах | |
| От: | _nn_![]() | ||
| Дата: | 16.05.09 10:11 |
| Здравствуйте, artem_korneev, Вы писали: _>Здравствуйте, ra88, Вы писали: R>>Попробуй R>>#pragma pack(4) _>Спасибо, помогло. Я удивлён, я думал, что #pragma pack это чисто майкрософтовское. _>Интересно, а будет ли это работать под другими компиляторами? Мне-то нужно поддерживать код для gcc, icc, visual studio, и ещё каких-то там. Надо попробовать. В принципе все поддерживают #pragma pack. Если ищется универсальное решение, то можно сделать например как в библиотеке lwip: ip.h bpstruct.h epstruct.h
Таким образом если компилятор поддерживает #pragma pack, pop можно воспользоваться этим, а если что-то другое как, скажем, __declspec(align) или __attribute__(aligned), то им.
|
| Re[4]: gcc, Выравнивание на 64-битных архитектурах | |
| От: | artem_korneev![]() | ||
| Дата: | 18.05.09 07:03 |
| Здравствуйте, _nn_, Вы писали: __>В принципе все поддерживают #pragma pack. Все — это кто? Действительно все, или только msvs, gcc и icc? __>
Если через if/elif, то у меня список большой получится. Мне нужно чтобы всё это поддерживалось разными версиями компиляторов MSVS, PG, GCC, ICC, SC, IVA. Вполне может быть, что список будет пополняться. А уж тестирование всего этого добра под всеми поддерживаемыми версиями всех компиляторов на разных операционных системах — то ещё удовольствие. Поэтому я пока решил эту проблему на уровне языка C++, а не средствами препроцессора. С уважением, Artem Korneev. |