Ответ 1
Вы можете найти обзор wikipedia. Более подробно на сайте IBM: Выравнивание данных: выпрямите и летите прямо
Я ищу хороший (полный) документ о выравнивании памяти в С++, типичных подходах, различиях между компиляторами и общими ошибками. Просто чтобы проверить правильность моего понимания темы и узнать что-то новое.
Этот вопрос вдохновлен моим ответом на другой вопрос, в котором я использовал следующую конструкцию:
char const buf[1000] = ...;
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // shift can be anything
Он подвергся критике как несоответствующий правилам выравнивания памяти. Не могли бы вы объяснить в качестве бонуса, почему этот подход ошибочен с точки зрения выравнивания памяти? Пример, когда он не работает, будет высоко оценен. Я знаю, что это плохой подход в целом, но я часто использую его в реализации сетевых протоколов, поэтому это скорее практический вопрос, чем теоретический.
Также, пожалуйста, не упоминайте строгий сглаживание здесь, это для другого вопроса.
Вы можете найти обзор wikipedia. Более подробно на сайте IBM: Выравнивание данных: выпрямите и летите прямо
Массивные массивы char
не имеют особых требований к их выравниванию. Таким образом, ваш буфер из тысячи символов может иметь нечетное смещение. Попытка прочитать int
из этого смещения (переопределенного как очевидный указатель на int) приведет либо к плохой производительности, либо даже к ошибке шины на некоторых аппаратных средствах, если компилятор не разделит его на отдельные операции чтения + битмаски.
Массированные массивы char
гарантированно выравниваются соответственно для хранения любого типа объекта, поэтому это всегда опция.
Для хранилища на основе без кучи используйте boost::aligned_storage
, который гарантирует правильное выравнивание пространства для общего использования.
Представьте, что адреса должны быть выровнены по 16 байт, например, для PS3. А потом представьте, что сдвиг == 1. Тогда это наверняка будет несимметричным 16-байтовым указателем, который не будет работать на этой машине.