zHz00 Untitled

воскресенье, 11 декабря 2016
23:59 Ещё про упаковку
Я написал о проблеме, которая может возникнуть из-за неожиданного выравнивания полей структуры, но не написал, что же с этим делать.

Сначала несколько важных замечаний:
  • Встретил я указанную проблему в компиляторе GCC под ARM.
  • По документации результат #pragma pack распространяется на упаковку полей структуры, описание которой идёт сразу после директивы. То есть, по идее, значение упаковки не должно было переноситься на дальнейшие структуры. Однако оно переносилось.
  • #pragma pack -- микрософтовская штучка и была добавлена в GCC для совместимости. В компиляторах от микрософт она может работать несколько иначе. В GCC есть более мощный аналог -- __attribute__((packed(...)))


Решение такое. Надо просто принудительно при описании каждой структуры перед ней прописывать желаемую упаковку. Однако тут появляется проблема -- если после нашей структуры будут другие структуры, они получат уже новую упаковку, что потенциально попортит жизнь библиотекам, заголовочные файлы которых включены после нашего. Попортят тем же способом, каким кто-то попортил жизнь нам. Однако разработчики предусмотрели на этот случай возможность сохранения и восстановления значения упаковки. Итак, вот что надо делать при описании каждой структуры:

#pragma pack(push)
#pragma pack()
//#pragma pack(N)
struct A
{
//...
};
#pragma pack(pop)


pack(push) в начале сохранит, а pack(pop) в конце восстановит старое значение упаковки (вдруг оно будет кому-то нужно?).

pack() без параметров установит значение упаковки по-умолчанию, которое можно настроить перед началом компиляции (подробнее тут), что позволит гибко настраивать упаковку для различных архитектур. Если же нужна конкретная упаковка для данной структуры, можно написать #pragma pack (N), где вместо N должно стоять число 1, 2 или 4 (компиляторы микрософт для 64-битных систем также поддерживают 8 и 16). Идентификатор, сделанный через #define, вместо N подставить нельзя.

@темы: Программирование

URL
Сычев плакал, наверное он единственный из нашей команды к...
[*]www.yestoall.com/flashAPI/index.html Линк может оказ...
Сейчас начентся завершаюший епизод великого прорыва Кореи...
Вчера Мишка пришел с работы и забабахал клевый и очень вк...
Реальная книга
Мне нравится буква "Э": Энергия, эволюция, эг...

12.12.2016 в 05:03

12.12.2016 в 05:03
Даблпост.
URL

12.12.2016 в 08:01

12.12.2016 в 08:01
Спасибо, удалил лишний.
URL

12.12.2016 в 23:14

12.12.2016 в 23:14
Слышал байку, что в описании директивы pragma в стандарте C++ сказано: "Компилятор волен трактовать директиву как ему вздумается", поэтому первые версии gcc, встречая директиву pragma, запускали какую-то линуксовую игру.
URL

12.12.2016 в 23:31

12.12.2016 в 23:31
himself, АХАХАХАХА.
URL
Добавить комментарий

Расширенная форма

Подписаться на новые комментарии
Получать уведомления о новых комментариях на E-mail