查询特定变量

时间:2016-03-25 09:05:39

标签: c++ c++11 memory-alignment

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字节边界上对齐。标准中是否有任何内容可以执行此类查询?

3 个答案:

答案 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)

目前由EWG 98处理。我在此提交了a paper

  

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;