alignof 返回类型自然对齐所需的字节数(2的幂),非 sizeof;alignas 强制指定对齐(须为2的幂且不小于默认值),影响内存布局与性能。
很多人误以为 alignof(int) 会返回 sizeof(int),其实它返回的是该类型在内存中**自然对齐所需的字节数**。比如在大多数 x64 系统上:alignof(double) 是 8,但 sizeof(double) 也是 8;而 alignof(std::max_align_t) 通常是 16,远大于多数基础类型的大小。
对齐值影响结构体布局:编译器会在成员之间插入填充字节,确保每个成员起始地址是其 alignof 的整数倍。
alignof 结果总是 2 的幂(如 1、2、4、8、16…)alignas
不是“建议”,而是强制约束。若你写 alignas(32) struct S { ... };,那 sizeof(S) 可能因填充变大,且每次 new S 或局部变量分配都保证地址 % 32 == 0。
常见错误:
立即学习“C++免费学习笔记(深入)”;
alignas(3) —— 编译失败,非 2 的幂alignas(1) char buf[64]; —— 合法但无意义,char 默认对齐就是 1alignas(64) std::vector v; —— 无效,alignas 对非 POD 类型的变量声明不改变其内部内存布局真正有效的场景是自定义缓冲区或与 SIMD 指令配合:
alignas(32) float simd_array[8]; // 适配 AVX2 的 256-bit load
成员排列顺序直接影响填充量。例如:
struct Bad {
char a;
double b; // 编译器插 7 字节填充
char c;
}; // sizeof(Bad) == 24(x64)
struct Good {
double b;
char a;
char c;
}; // sizeof(Good) == 16(紧凑排布)
此时再加 alignas(16) 不会进一步增大体积,因为最大成员 double 已要求 8 字节对齐,而结构体本身对齐已满足 16 字节边界(取决于目标平台和 ABI)。
关键原则:
double、__m128、指针等)放在前面alignas 显式提升整个结构体对齐,仅当需要缓存行对齐(如避免 false sharing)或对接硬件要求时才用alignas 不能降低已有对齐(比如对 int 加 alignas(1) 无效)运行时验证是否真对齐,比静态推测更可靠:
struct alignas(64) CacheLineAligned {
int data;
};
CacheLineAligned obj;
std::cout << "address: " << (uintptr_t)&obj << "\n"; // 应为 64 的倍数
std::cout << "offsetof(data): " << offsetof(CacheLineAligned, data) << "\n"; // 应为 0
容易忽略的点:
malloc 返回的内存只保证 max_align_t 对齐(通常是 16),不够用得换 aligned_alloc(64, size)
alignof 可能因模板参数不同而变化(比如 std::array 对齐仍是 1,但 std::array 就是 8)对齐不是越严越好——盲目用 alignas(4096) 会让小对象浪费大量内存,还可能破坏 CPU 预取效率。