Выравнивание структур Си
Имею структуру, которую хочу считать за одно применение fread. Если я не отключаю выравнивание с помощью #pragma pack(pop) считываются некорректные данные, но, насколько я понял, отключение выравнивания является плохой практикой. Есть ли какая-то альтернатива?
Сама структура:
typedef struct BITMAPINFOHEADER
{
DWORD biSize; // Размер структуры
LONG biWidth; // Ширина изображения в пикселах.
LONG biHeight; // Высота изображения в пикселах.
WORD biPlanes; // Количество плоскостей. Равно 1 при кол-ве цветов >=256.
WORD biBitCount; // Глубина цвета в битах на пиксель.
DWORD biCompression; // Тип сжатия.
DWORD biSizeImage; // Размер изображения в байтах.
LONG biXPelsPerMeter; // Горизонтальное разрешениe.
LONG biYPelsPerMeter; // Вертикальное разрешениe.
DWORD biClrUsed; // Количество используемых цветов кодовой таблицы, 0 == max.
DWORD biClrImportant; // Количество используемых (выжных) цветов кодовой таблицы. 0 == max.
} BMI;
Спасибо!
Ответы (2 шт):
#pragma(push,1)
отключает выравнивание, а именно - устанавливает выравнивание в 1 байт, что эквивалентно отключению.
#pragma(pop)
как раз напротив - его возвращает в предыдущие состояние.
Отключение выравнивания не вредит структурам в операциях ввода вывода. Писать в файл упакованные данные в обычные прикладные можно и нужно.
Выравнивание нужно для операций с большими массивами, базами данных, графикой и подобными штуками. Суть в том что прочитав данные в регистр процессора не нужно их там обрезать, сдвигать. Это ускоряет поск, сортировку, умножение матриц и всякое такое в разы, что критично для большого объёма данных.
Даже в случае обработки данных в выровненных структурах записывать и читать файл можно копируя поля в/из невыровненной версии структуры.