alignof 返回类型在内存中必须满足的最小字节对齐边界,即该类型对象起始地址必须为返回值的整数倍;它是编译期常量,只接受类型名,结果恒为2的幂,不反映实际地址或大小。

alignof 返回的是类型对齐要求,不是地址或大小
alignof 查询的是某类型在内存中**必须满足的最小字节对齐边界**,即该类型对象的起始地址必须是返回值的整数倍。它不返回变量实际存放位置、也不返回 sizeof,更不操作运行时地址。
常见误判:看到 struct { char a; int b; } 中 b 偏移为 4,就以为 alignof 在“算偏移”——其实它只说明 int 要求 4 字节对齐,而结构体里 b 的偏移由整体布局规则决定,alignof 不参与计算。
-
alignof(int)通常是 4,表示所有int对象地址 % 4 必须为 0 -
alignof(double)在 x64 上多为 8,但某些嵌入式平台可能是 4 - 空结构
struct {}的alignof是 1,但sizeof至少为 1 - 用户定义类型(如 struct)的
alignof取其所有成员alignof的最大值,再向上对齐到编译器默认粒度(如 8 或 16)
alignof 是编译期常量,不能用于运行时地址判断
alignof(T) 展开后就是一个 std::size_t 字面量,比如 alignof(double) 在多数平台直接等价于 8。它不读内存、不检查指针、不接受变量名或表达式——只接受类型名或带括号的类型标识符。
典型错误写法:if (ptr % alignof(double)) —— 这里漏了三步:把 ptr 转成 uintptr_t、用模运算、且模数必须是 2 的幂。正确做法是:
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
if (addr % 8 != 0) { /* not aligned to double */ }</uintptr_t>
-
alignof无法告诉你某个具体指针是否对齐,它只提供目标对齐值 - 运行时对齐判定必须靠地址数值运算,且对齐值必须是 2 的幂(3、6、12 都无效)
- 模板函数中可传入
alignof(T)作为参数,但判定逻辑仍需显式做模运算
结构体的 alignof 不等于最大成员的 alignof
结构体的 alignof 确实通常由其最严格成员决定,但最终结果还要受编译器默认对齐策略约束。例如在 MSVC 默认设置下,即使结构体只含 char 和 short(各自 alignof 为 1 和 2),其 alignof 仍可能是 8。
这是因为编译器会将结构体整体对齐提升到平台“基本对齐粒度”,以适配 std::max_align_t 或 SIMD 指令要求。这个提升是隐式的,不受成员影响。
- 用
#pragma pack(1)可强制压缩,但alignof也会随之变为 1 - 用
alignas(32)显式修饰结构体,alignof就是 32,不管成员如何 -
alignof值永远是 2 的幂(1/2/4/8/16/32…),不可能是奇数或非 2 幂合数
alignof 和 aligned_alloc / _mm_malloc 的配合要点
调用 aligned_alloc 或 Intel 的 _mm_malloc 时,第二个参数必须是 2 的幂,且通常设为 alignof(T)。但这只是起点——真正要安全使用,还需注意:
-
aligned_alloc(alignment, size)要求size是alignment的整数倍,否则行为未定义 -
alignof(T)给出的是最小建议值;若用于 AVX-512 缓存行优化,可能需要硬编码 64 而非依赖alignof - 分配后仍需用模运算验证地址是否真对齐,尤其在跨平台或旧 libc 环境下
- 释放时必须匹配分配方式:
aligned_alloc→free,_mm_malloc→_mm_free
最易被忽略的一点:对齐要求是硬件+ABI 共同决定的,alignof 只反映当前编译环境下的取值,换平台、换 ABI(如 ILP32 vs LP64)、甚至换编译选项(/Zp 或 -fpack-struct)都可能改变结果。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











