C ++ 11引入了alignas
specifier来指定变量的对齐方式,alignof
operator来查询类型的默认对齐方式。但是,我没有看到任何方法来获得特定变量的对齐方式。让我们采取以下简单的例子:
alignas(16) float* array;
以下是我们可以采取的措施:
alignof(float*)
返回8,这显然不是我们想要的。alignof(array)
返回16,这正是我们想要的,但这是一个编译器扩展;标准指定的alignof
不能用于特定变量。alignof(decltype(array))
返回8,这是非常期待但不是我们想要的。std::alignment_of
是根据alignof
实施的,因此无济于事。我想要一种机制来确认特定变量array
是否在16字节边界上对齐。标准中是否有任何内容可以执行此类查询?
答案 0 :(得分:9)
您可以尝试使用以下内容:
uintptr_t
上面假设一个扁平的地址空间,char *
上的算术等同于void *
上的算术。
虽然这些条件适用于大多数现代平台,但标准并不要求这些条件。
在将uintptr_t
投射到uintptr_t
时执行任何转换完全有可能,只要在从void *
转回{{1}时转换可以反转(见What is uintptr_t data type)。
N4201中的更多详细信息(除其他外,它提出了is_aligned()
操作)。
修改
这里需要
volatile
吗?
它允许类似:
alignas(16) volatile float a;
assert(is_aligned(&a, 16));
如果没有volatile
,则会收到错误
来自' volatile float *' to' const void *'第一个参数
进一步参考:
答案 1 :(得分:4)
alignas
说明符适用于对象,影响它们的对齐要求,但不影响它们的类型。因此,目前无法确定对象的实际对齐要求。本文建议允许alignof
应用于对象和引用。
此时你能做的最好的事情是定义一个保持变量对齐的单独变量。
答案 2 :(得分:2)
你可以试试这个:
template<size_t size, typename T>
constexpr bool IsAlignedAs(const T& v)
{
return (reinterpret_cast<const size_t>(&v) % size) == 0;
}
std::cout << IsAlignedAs<16>(array) << std::endl;
std::cout << IsAlignedAs<32>(array) << std::endl;