зачем нам нужна структура #pragma pack
для typedef
в C++? В частности, когда вы используете эту структуру в сетевой связи.
#pragmapack в C++
Ответы (4)
#pragma pack
управляет выравниванием членов структуры. Обычное значение по умолчанию — 8, что гарантирует, что элементы длиной до 8 байт будут выровнены по адресу, кратному их размеру. Например, двойной или 64-битный указатель. Чтение или запись неправильно выровненного двойника может быть довольно дорогим, обычно в три раза медленнее, если он выходит за границу строки кэша ЦП. Это выравнивание может создать неиспользуемое пространство между элементами, называемое заполнением.
Такое выравнивание часто не подходит для сетевых фреймов, они, как правило, плотно упакованы без каких-либо отступов, #pragma pack(push, 1)
Директива пакета #pragma изменяет текущее правило выравнивания только для членов структур, объявления которых следуют за директивой. Он не влияет на выравнивание структуры напрямую, но, влияя на выравнивание элементов структуры, может влиять на выравнивание всей структуры в соответствии с правилом выравнивания.
Если вам просто нужно, чтобы две системы с одинаковыми настройками общались друг с другом (тест,...), вы можете отправлять структуры, при условии, что они представляют собой просто POD (обычные старые данные) (указатели, виртуальные таблицы, std::strings.. . нельзя использовать). Так что пакет не нужен.
Если системы не имеют одинаковых настроек (или неизвестны), вам нужно отправлять данные, сериализованные в протоколе, поэтому упакованные структуры не годятся. Проще всего проверить, доступны ли действующие протоколы.
Компиляторы будут «дополнять» поля и подполя структуры, т. е. организовывать их в памяти пустыми участками памяти, которые ничего не содержат посередине. Это делается для повышения эффективности, как объясняет ответ Ханса Пассана.
Различные настройки компилятора/цели/оптимизации могут по-разному заполняться, преобразовывая одинаковые «логические» структуры в неодинаковые представления памяти, поэтому, если две взаимодействующие машины передают структуру между собой, они могут не понять друг друга.
#pragma pack — это ваш способ ограничить свободу компилятора.
#pragma pack(push, 1) приказывает компилятору вообще не дополнять. Если вы сделаете это с двумя идентичными структурами, определенными в разных кодах, они будут одинаково представлены в памяти. Затем вы можете безопасно отправлять содержимое структуры в одном приложении через какой-либо протокол, используя указатель и sizeof(), получать его на другой стороне и записывать прямо над идентичной структурой, также используя указатель и sizeof().
pragma pack
: msdn.microsoft.com/en-us/library/aa273913%28v=vs.60%29.aspx - person bezmax   schedule 22.12.2010