Структура по ходу вообще не нужна Код (Text): union { uint32_t pixel; struct { uint8_t r; uint8_t g; uint8_t b; uint8_t a; } colors; } m; .... m.colors.r = red; m.colors.g = green; m.colors.b = blue; pixel = &(m.pixel);
> Структура по ходу вообще не нужна что, что? ) а если каждый uint8_r выравнивается по границе в 4 байта?
Простите, а чем а чем не устраивает "упакованная" структура? Вариант для gcc http://sig9.com/articles/gcc-packed-structures Вариант для MSVC http://msdn.microsoft.com/en-us/library/2e70t5y1(VS.80).aspx Собственно, для этого ( вроде как ) и придумывалось. Кросплатформенности все равно не получите, поскольку выравнивание отдано на откуп разработчикам компиляторов и каждый делает по своему ( хотя и похоже на "соседей" ). PS: Увлекаться упаковкой не стоит, поскольку для ARM'а, априори будет генериться неоптимальный код. Насколько помню, там все выравнивается по границе в 4-ре байта, следовательно, при работе с отдельными байтами их придется постоянно "распаковавать/запаковывать". Ну и совсем плохо будет, если середина int'а попадет на границу выравнивания.
есть такой вариант: Код (Text): struct color_t { uint8_t components[4]; uint8_t& a() { return components[0]; } uint8_t& r() { return components[1]; } uint8_t& g() { return components[2]; } uint8_t& b() { return components[3]; } };
Считаете, что элементы массива не выравниваются и расположены строго последовательно? Лично у меня по этому вопросу пробел в знаниях... Впрочем, в противном случае не работала бы "арифметика" указателей. Увы, разместить в массиве можно только элементы одного типа. Хотя, в рамках топика, ИМХО, изящное решение.
Там (собственно как и везде) тип выравнивается до кратности адреса размеру этого типа. Просто на х86 с невыровнянными данными процессор работать может (хоть и с падением производительности), а ARM - нет. Это гарантируется стандартом.
Кстати, не совсем понятен такой момент. Вот есть спецификация, например, на формат файла: Код (Text): data offset(octets) size(octets) id 0 2 size 2 4 name 6 16 ... Этой спецификации я могу сопоставить структуру: Код (Text): struct file_header_t { uint8_t id; uint16_t size; char_t name[16]; // ... }; Для того, чтобы правильно считать данные из файла я должен считывать каждое поле в отдельности. В противном случае выравнивание может нарушить последовательность. Получается так? С другой стороны, каждый раз дёргать вызов read довольно накладно. Наиболее оптимально - смапить файл.
мапить и читать каждое поле отдельно. В бусте, вроде, есть поток ввода-вывода, завязаный на мапу файла. ИМХО, идеальный вариант. И кроссплатформенность не страдает и с быстродействием проблем не будет.
имеется ввиду CreateFileMapping MapViewOfFile. В бусте, есть файловый поток mapped_file, предоставляющий аналогичные возможности.