alignof 运算符
查询类型的对齐要求。
语法
alignof( 类型标识 )
返回 std::size_t 类型的值。
返回由类型标识所指示的类型的任何实例所要求的对齐字节数,该类型可以是完整对象类型、元素类型完整的数组类型或者到这些类型之一的引用类型。
如果类型是引用类型,那么运算符返回被引用类型的对齐要求;如果类型是数组类型,那么返回元素类型的对齐要求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#include <iostream> struct Foo { int i; float f; char c; };
struct alignas(alignof(long double)) Foo2 { }; struct Empty {}; struct alignas(64) Empty64 {}; int main() { std::cout << "对齐字节数" "\n" "- char :" << alignof(char) << "\n" "- 指针 :" << alignof(int*) << "\n" "- Foo 类 :" << alignof(Foo) << "\n" "- Foo2 类 :" << alignof(Foo2) << "\n" "- 空类 :" << alignof(Empty) << "\n" "- 带 alignas(64) 的空类:" << alignof(Empty64) << "\n"; } 可能的输出:
对齐字节数 - char :1 - 指针 :8 - Foo 类 :4 - Foo2 类 :16 - 空类 :1 - 带 alignas(64) 的空类:64
|
alignas 说明符
指定类型或对象的对齐要求。
语法 |
说明 |
alignas( 表达式 ) |
表达式 必须是求值为零或合法的对齐或扩展对齐的整型常量表达式。 |
alignas( 类型标识 ) |
等价于 alignas(alignof(类型标识)) |
alignas( 包 … ) |
等价于对同一说明应用多个 alignas 说明符,逐个对应于形参包的各个成员,形参包可以是类型或非类型形参包。 |
alignas 说明符可用于:
- 类的声明或定义;
- 非位域类数据成员的声明;
- 变量声明,除了它不能应用于下列内容:
这种声明所声明的对象或类型的对齐要求将等于用于该声明的所有 alignas 说明符中最严格(最大)的非零 表达式,除非这会削弱类型的自然对齐。
如果某个声明上的最严格(最大)alignas 比当它没有任何 alignas 说明符的情况下本应有的对齐更弱(即弱于其原生对齐,或弱于同一对象或类型的另一声明上的 alignas),那么程序非良构:
1 2
| struct alignas(8) S {}; struct alignas(1) U { S s; };
|
无效的非零对齐,例如 alignas(3) 非良构。
同一声明上,比其他 alignas 弱的有效的非零对齐被忽略。
始终忽略 alignas(0)。
按 ISO C11 标准,C 语言有 _Alignas 关键词,并于头文件 <stdalign.h> 中将 alignas 定义为展开成该关键词的预处理器宏。
在 C++ 中这是关键词,且
头文件 <stdalign.h> 与 并不定义这个宏。不过它们仍定义宏常量 __alignas_is_defined。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
struct alignas(alignof(float)) struct_float { };
struct alignas(32) sse_t { float sse_data[4]; };
alignas(64) char cacheline[64]; #include <iostream> 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
|