Как установить выравнивание независимо от платформы? - PullRequest
4 голосов
/ 21 сентября 2011

В последней версии стандарта c ++ 11 глава 3.11 говорит о выравнивании.
Позже, глава 7.6.1 определяет, как определить выровненные структуры (или переменные?)

Если я определю структуру следующим образом:

alignas(16) struct A
{
  int n;
  unsigned char[ 1020 ];
};

означает ли это, что все экземпляры класса A будут выровнены до 16 байтов?

Или я должен сделать это, как в следующем коде?

struct A
{
  char data[300];
};
alignas(16) A a;

Если оба примера неверны, как это сделать правильно?

PS Я не ищу решение, зависящее от компилятора.

1 Ответ

3 голосов
/ 21 сентября 2011

Выравнивание в первую очередь является свойством типов.

Может быть переопределено для типа с alignas;alignas может также использоваться для назначения нового значения выравнивания для конкретного объекта.

Итак, оба примера верны и будут иметь семантику, которую вы предполагали.

[n3290: 3.11/1]: Типы объектов имеют требования к выравниванию (3.9.1, 3.9.2), которые накладывают ограничения на адреса, по которым может быть выделен объект этого типа. alignment - это определенное реализацией целочисленное значение, представляющее число байтов между последовательными адресами, по которым данный объект может быть выделен. Тип объекта накладывает требование выравнивания на каждый объект этого типа; более строгое выравнивание можно запросить с помощью спецификатора выравнивания (7.6.2).

[n3290: 7.6.2/1]: An спецификатор выравнивания может применяться к переменной или к элементу данных класса , но его нельзя применять к битовому полю, параметру функции, формальному параметру предложения catch (15.3),или переменная, объявленная со спецификатором класса хранения register. Спецификатор выравнивания может также применяться к объявлению класса или типа перечисления. Спецификатор выравнивания с многоточием является расширением пакета (14.5.3).

[n3290: 7.6.2/2]: Когда спецификатор выравнивания имеет форму alignas( assignment-expression ):

  • , выражение-присваивание должно быть целочисленным константным выражением
  • , есливыражение константы оценивается как фундаментальное выравнивание, требование выравнивания объявленного объекта должно быть указанным фундаментальным выравниванием
  • , если выражение константы оценивается как расширенное выравнивание, и реализация поддерживает это выравнивание в контексте объявления,выравнивание объявленной сущности должно быть таким выравниванием
  • , если константное выражение оценивается как расширенное выравнивание и реализация не поддерживает это выравнивание в контексте объявления, программа плохо сформирована
  • если константное выражение равно нулю, aligСпецификатор не должен иметь никакого эффекта
  • , в противном случае программа некорректна.
...