alignas specifier (начиная с C++11)
Определяет требование по выравниванию для типа или объекта.
Содержание |
[править] Синтаксис
alignas( выражение )
|
|||||||||
alignas( идентификатор-типа )
|
|||||||||
alignas( пакет ... )
|
|||||||||
[править] Объяснение
Спецификатор 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> не определяют такой макрос. Однако они определяют макро константу __alignas_is_defined. |
(до C++20) |
заголовок <stdalign.h> не определяет такой макрос. Однако он определяет макро константу __alignas_is_defined. |
(начиная с 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
|