alignas specifier (начиная с C++11)
Определяет требование по выравниванию для типа или объекта.
Синтаксис
alignas( выражение )
|
|||||||||
alignas( идентификатор-типа )
|
|||||||||
alignas( пакет ... )
|
|||||||||
alignas(выражение) должно быть целочисленным константным выражением, эквивалентным нулю или значением, удовлетворяющим правилам для выравнивания или для расширенного выравнивания.alignas(alignof(тип)).Объяснение
Спецификатор alignas может быть применён к:
- объявлению или определению класса;
- объявлению элемента данных класса, не являющегося битовым полем;
- объявлению переменной, за исключением того, что он не может быть применён к следующему:
- параметру функции;
- параметру исключения предложения catch.
Объект или тип, объявленный таким образом, будет иметь требование по выравниванию равное самому строгому (самому широкому) ненулевому выражению из всех спецификаторов alignas, использованных в данном объявлении, если только оно не ослабит базовое выравнивание для этого типа.
Если самый строгий (самый широкий) спецификатор alignas, применённый к объявлению, слабее, чем выравнивание, которое оно бы имело без всяких спецификаторов alignas (т.е. слабее, чем его базовое выравнивание, или слабее, чем спецификатор alignas, применённый к другому объявлению того же объекта или типа), программа считается неправильной:
struct alignas(8) S {};
struct alignas(1) U { S s; }; // ошибка: без alignas(1) выравнивание U было бы 8 байтов
Ненулевые требования по выравниванию, такие как alignas(3), не удовлетворяют правилам и являются неправильными.
Игнорируются удовлетворяющие правилам ненулевые выравнивания, являющиеся более слабыми, чем другие alignas для того же объявления.
alignas(0) игнорируется всегда.
Примечание
Согласно стандарту ISO C11, в языке C есть ключевое слово _Alignas и в <stdalign.h> определён макрос препроцессора alignas, раскрывающийся в это ключевое слово.
В C++ это ключевое слово, и
|
заголовки <stdalign.h> и <cstdalign> не определяют такой макрос. Однако они определяют макро константу |
(до C++20) |
|
заголовок <stdalign.h> не определяет такой макрос. Однако он определяет макро константу |
(начиная с C++20) |
Ключевые слова
Пример
#include <iostream>
// каждый объект типа struct_float будет выровнен по границе alignof(float)
// (обычно 4):
struct alignas(float) struct_float
{
// ваше определение здесь
};
// каждый объект типа sse_t выровнен по 32-байтовой границе:
struct alignas(32) sse_t
{
float sse_data[4];
};
// массив "cacheline" будет выровнен по 64-байтовой границе:
alignas(64) char cacheline[64];
int main()
{
struct default_aligned
{
float data[4];
} a, b, c;
sse_t x, y, z;
std::cout
<< "alignof(struct_float) = " << alignof(struct_float) << '\n'
<< "sizeof(sse_t) = " << sizeof(sse_t) << '\n'
<< "alignof(sse_t) = " << alignof(sse_t) << '\n'
<< "alignof(cacheline) = " << alignof(alignas(64) char[64]) << '\n'
<< std::hex << std::showbase
<< "&a: " << &a << '\n'
<< "&b: " << &b << '\n'
<< "&c: " << &c << '\n'
<< "&x: " << &x << '\n'
<< "&y: " << &y << '\n'
<< "&z: " << &z << '\n';
}
Возможный вывод:
alignof(struct_float) = 4
sizeof(sse_t) = 32
alignof(sse_t) = 32
alignof(cacheline) = 64
&a: 0x7fffcec89930
&b: 0x7fffcec89940
&c: 0x7fffcec89950
&x: 0x7fffcec89960
&y: 0x7fffcec89980
&z: 0x7fffcec899a0
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| CWG 1437 | C++11 | alignas можно использовать в объявлениях псевдонимов | запрещено |
| CWG 2354 | C++11 | alignas может применяться к объявлению перечисления | запрещено |
Смотри также
оператор alignof(C++11)
|
запрашивает требования к выравниванию типа |
(C++11) |
получает требования к выравниванию типа (шаблон класса) |
Документация C по _Alignas, alignas
| |