Исходные настройки окна:
Окно непрозрачно.
Цвет фона желтый.
Рамка отображается.
Цвет рамки зеленый.
Стиль рамки штриховой.
Настройки окна с использованием представления unsigned short:
Окно прозрачно.
Цвет фона черный.
Рамка не отображается.
Стиль рамки сплошной.
Цвет рамки черный.
Комбинация битов 10110000101010000000000000000000
Измененные настройки окна:
Окно прозрачно.
Цвет фона желтый.
Рамка отображается.
Цвет рамки зеленый.
Стиль рамки штриховой.
Настройки окна с использованием представления unsigned short:
Окно прозрачно.
Цвет фона голубой.
Рамка отображается.
Стиль рамки пунктирный.
Цвет рамки красный.
Комбинация битов 10110000101010000001001000001101
Здесь изменения затрагивают те же биты, что и ранее, но в системе Macintosh PowerPC загрузка структур в память осуществляется по-другому. В частности, первое битовое поле загружается, начиная со старшего, а не младшего бита. Поэтому представление структуры касается первых 16 битов (которые следуют в порядке, отличающемся от версии IBM PC), тогда как представление unsigned int затрагивает последние 16 битов. Таким образом, допущения, сделанные относительно позиций битов в листинге 15.4, для Macintosh PowerPC некорректны, а побитовые операции, применяемые для изменения настроек прозрачности и цвета фона, изменяют не те биты.
Средства выравнивания (С11)
Средства выравнивания С11 по своей природе больше ориентированы на манипулирование байтами, чем битами, но они также отражают возможность языка С иметь дело с оборудованием. В этом контексте выравнивание относится к тому, как объекты располагаются в памяти. Например, для максимальной эффективности система может требовать, чтобы значение типа double хранилось в памяти по адресу, кратному 4, но разрешать значению типа char храниться по любому адресу. Большинству программистов редко когда придется заботиться о выравнивании. Но в некоторых ситуациях контроль над выравниванием позволяет извлечь выгоду, например, при передаче данных из одного физического места в другое либо при вызове инструкций, которые оперируют на множестве элементов данных одновременно.
654 Глава 15
Операция Alignof выдает требования к выравниванию указанного типа. Для ее использования необходимо после ключевого слова _Alignof поместить имя типа в круглых скобках:
size_t d_align = _Alignof(float);
Полученное значение, скажем, 4 для d_align, говорит о том, что объекты float имеют требование к выравниванию, соответствующее 4. Это означает, что 4 является количеством байтов между следующими друг за другом адресами для хранения значений упомянутого типа. В общем случае значения выравнивания должны быть неотрицательными целыми числами, которые представляют собой степень 2. Более высокие значения выравнивания считаются более жесткими или более строгими, чем меньшие значения, в то время как меньшие значения трактуются как более слабые.
С помощью спецификатора _Alignas можно запрашивать конкретное выравнивание для переменной или типа. Однако вы не должны запрашивать выравнивание, которое слабее фундаментального выравнивания, принятого для типа. Например, если требование к выравниванию для float составляет 4, не запрашивайте значение выравнивания, равное 1 или 2. Этот спецификатор применяется как часть объявления, и за ним следует пара круглых скобок, содержащая либо значение выравнивания, либо тип:
_Alignas(double) char cl;
_Alignas(8) char c2;
unsigned char _Alignas(long double) c_arr[sizeof(long double)];
На заметку!
На момент написания книги компилятор Clang (версии 3.2) требовал, чтобы спецификатор Al ignas (тип) располагался после спецификатора типа, как в третьей строка приведенного выше кода. Тем не менее, компилятор GCC 4.7.3 распознает оба порядка следования, как и последующая версия (3.3) компилятора Clang.
В листинге 15.5 показан короткий пример использования Alignas и Alignof. Листинг 15.5. Программа align.с

Манипулирование битами 655
Вот пример вывода:
Выравнивание char: 1
Выравнивание double: 8 &dx: 0x7fff5fbff660 &са: 0x7fff5fbff65f &сх: 0x7fff5fbff65e &dz: 0x7fff5fbff650 &cb: 0x7fff5fbff64f &cz: 0x7fff5fbff648
В нашей системе значение выравнивания 8 для типа double подразумевает, что значения этого типа сохраняются по адресам, кратным 8. Шестнадцатеричные адреса, заканчивающиеся на 0 или 8, являются кратными 8, и адреса такого вида применялись для двух переменных double, а также переменной char по имени cz, которой было назначено значение выравнивания для типа double. Поскольку значением выравнивания для char было 1, компилятор мог использовать для переменных этого типа любые адреса.
Читать дальше