Где я могу найти документацию по выравниванию памяти С++ на разных платформах/компиляторах?

Я ищу хороший (полный) документ о выравнивании памяти в С++, типичных подходах, различиях между компиляторами и общими ошибками. Просто чтобы проверить правильность моего понимания темы и узнать что-то новое.

Этот вопрос вдохновлен моим ответом на другой вопрос, в котором я использовал следующую конструкцию:

char const buf[1000] = ...;
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // shift can be anything

Он подвергся критике как несоответствующий правилам выравнивания памяти. Не могли бы вы объяснить в качестве бонуса, почему этот подход ошибочен с точки зрения выравнивания памяти? Пример, когда он не работает, будет высоко оценен. Я знаю, что это плохой подход в целом, но я часто использую его в реализации сетевых протоколов, поэтому это скорее практический вопрос, чем теоретический.

Также, пожалуйста, не упоминайте строгий сглаживание здесь, это для другого вопроса.

Ответы

Ответ 2

Массивные массивы char не имеют особых требований к их выравниванию. Таким образом, ваш буфер из тысячи символов может иметь нечетное смещение. Попытка прочитать int из этого смещения (переопределенного как очевидный указатель на int) приведет либо к плохой производительности, либо даже к ошибке шины на некоторых аппаратных средствах, если компилятор не разделит его на отдельные операции чтения + битмаски.

Массированные массивы char гарантированно выравниваются соответственно для хранения любого типа объекта, поэтому это всегда опция.

Для хранилища на основе без кучи используйте boost::aligned_storage, который гарантирует правильное выравнивание пространства для общего использования.

Ответ 3

Представьте, что адреса должны быть выровнены по 16 байт, например, для PS3. А потом представьте, что сдвиг == 1. Тогда это наверняка будет несимметричным 16-байтовым указателем, который не будет работать на этой машине.