Сильная структура С++ для плотной упаковки

Я пытаюсь читать в двоичном файле. Проблема в том, что создателю файла не потребовалось времени для правильного выравнивания структур данных с их естественными границами, и все упаковано плотно. Это затрудняет чтение данных с использованием структур С++.

Есть ли способ принудительно упаковать struct?

Пример:

struct {
    short a;
    int b;
}

Вышеупомянутая структура составляет 8 байт: 2 для short a, 2 для заполнения, 4 для int b. Однако на диске данные составляют всего 6 байтов (не имеющих 2 байта заполнения для выравнивания)

Имейте в виду, что фактические структуры данных - это тысячи байтов и много полей, включая пару массивов, поэтому я бы предпочел не читать каждое поле отдельно.

Ответ 1

Если вы используете GCC, вы можете сделать struct __attribute__ ((packed)) { short a; int b; }

На VС++ вы можете сделать #pragma pack(1). Эта опция также поддерживается GCC.

#pragma pack(push, 1)
struct { short a; int b; }
#pragma pack(pop)

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

Ответ 2

Для указания 1-байтовой упаковки вам необходимо использовать директиву, не относящуюся к стандарту, для компилятора. Например, под Windows:

#pragma pack (push, 1)

Проблема заключается в том, что создателю файла не уделялось должного внимания байт выравнивает структуры данных, и все упаковано плотно.

Собственно, дизайнер поступил правильно. Заполнение - это то, что может сказать стандарт, но он не говорит, сколько отступов следует применять в каких случаях. В стандарте даже не указано, сколько бит находится в байте. Несмотря на то, что вы можете предположить, что, хотя эти вещи не указаны, они все равно должны быть такими же разумными для современных машин, что просто не так. На 32-битной машине Windows, например, заполнение может быть одним, тогда как в 64-битной версии Windows может быть что-то еще. Может быть, это будет одно и то же - это не главное. Дело в том, что вы не знаете, что будет дополнением для разных систем.

Таким образом, "упаковывая его в тупик" разработчик сделал единственное, что мог, - используйте некоторую упаковку, чтобы он мог быть разумно уверен, что каждая система сможет понять. В этом случае общепринятая упаковка заключается в том, чтобы не использовать отступы в структурах, сохраненных на диске или отправленных по проводам.