Для основных типов alignof(T) == sizeof(T)
подходит для большинства современных ABI, но это не гарантируется. Стандарт C++ оставляет выравнивание в основном определяется реализацией, с учетом только этих ограничений (см [basic.align] и [basic.fundamental] в C++ 11):
alignof(T) <= sizeof(T)
. Это не является явным в стандарте, но между элементами массива никогда не было прокладки, поэтому независимо от выравнивания первого элемента T t[2]
элемент второй не может иметь выравнивание больше sizeof(T)
, и, следовательно, это максимальное выравнивание для тип T. Обратите внимание, что выравнивание переменной может быть больше, например, если на нем используется alignas
.
alignof(T) <= alignof(std::max_align_t)
, за исключением, возможно, в присутствии alignas
. Определяется ли определение alignas
«чрезмерное выравнивание» (с большей степенью детализации, чем max_align_t
).
char
, signed char
и unsigned char
все имеют одинаковое требование выравнивания (а именно: 1, так как sizeof(char) == 1
по определению).
Все неподписанные целые типы имеют то же требование выравнивания, что и соответствующий тип подписки.
wchar_t
, char16_t
и char32_t
имеют одинаковые требования к выравниванию как их «базовых» целочисленных типов.
Там есть были исторического АБИС, где основные типы не были приведены в соответствие с их размерами. Одним из хорошо известных примеров является double
и long double
в исходной системе V ABI для 80386, которые были выровнены только с 4-батной детализацией, несмотря на то, что они были 8 и 12 байтами соответственно. Это было связано с тем, что указатель стека был гарантирован только согласованностью с 4-батовой степенью детализации, и больно согласовывать элементы в записи активации с большей степенью детализации, чем указатель стека.
В настоящее время эта же проблема выравнивания стека может иметь типы векторов; например, на x86-64 указатель стека гарантированно выравнивается с 16-байтовой границей, но теперь аппаратное обеспечение поддерживает до 512-bit (64-byte) vectors.
Это единственные контрпримеры, о которых я лично знаю.Однако меня не удивило бы узнать, что ABI для встроенной среды с ограниченным объемом памяти нет выравнивание для ничего (то есть alignof(T) == 1
для всех T). Процессору это не так сложно обрабатывать, как раньше, особенно если нет виртуализации памяти.
Fun факт: C++ стандарт не требуют реализации, чтобы стек вызова функции. Это требует поддержки для рекурсии, и есть что-то, называемое «раскручивание стека», которое происходит, когда выбрасываются исключения, но все тщательно написано так, чтобы вы могли реализовать его с помощью чего-то другого, кроме линейных стеков, с которыми мы все знакомы.
Компилятор/платформа. И да, есть * платформы, где 32-битное целое не требуется для размещения на 32-битном выравнивании. На самом деле, возможны платформы, где 'int32_t' даже не существует *. – DevSolar
Единственным исключением из этого, что я видел в прошлом, является 'sizeof (double) == 8', но' alignof (double) == 4' (я считаю, что это распространено на 32-битных платформах, возможно, не так много сейчас, 64 бит становится нормой.) –
@PaulR: Норма * для чего *? Вы знаете, что для каждого 64-битного настольного/серверного процессора есть * тысячи * встроенных 8/16 бит процессоров? – DevSolar