查询特定变量的对齐方式

Query the alignment of a specific variable

C++11 引入了 alignas specifier to specify the alignment of a variable, and the alignof operator 来查询类型的默认对齐方式。但是,我看不到任何方法来对齐特定变量。让我们来看下面这个简单的例子:

alignas(16) float* array;

以下是我们可以做的事情:

我想要一种机制来确认特定变量 array 在 16 字节边界上对齐。标准中是否有执行此类查询的内容?

你可以试试这样的东西:

bool is_aligned(const volatile void *p, std::size_t n)
{
  return reinterpret_cast<std::uintptr_t>(p) % n == 0;
}

assert(is_aligned(array, 16));

上面假设一个平面地址 space 并且 uintptr_t 上的算术等同于 char *.

上的算术

虽然这些条件适用于大多数现代平台,但标准都没有要求。

在将 void * 转换为 uintptr_t 时,实现完全有可能执行任何转换,只要在从 uintptr_t 转换回 void * 时可以反转转换即可(参见 What is uintptr_t data type)。

N4201 中的更多详细信息(其中建议 is_aligned() 操作)。


编辑

is volatile necessary here?

它允许类似的东西:

alignas(16) volatile float a;

assert(is_aligned(&a, 16));

没有 volatile 你会得到错误

no known conversion from 'volatile float *' to 'const void *' for 1st argument

进一步参考:

  • Why and when is cast to char volatile& needed?
  • Why is a point-to-volatile pointer, like "volatile int * p", useful?

你可以试试这个:

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;

目前由 EWG 98. I submitted a paper 处理:

The alignas specifier is applicable to objects, affecting their alignment requirement but not their type. It is therefore currently not possible to determine an object's actual alignment requirement. This paper proposes to permit application of alignof to objects and references.

此时你能做的最好的事情就是定义一个单独的变量来保持变量的对齐。