查询特定变量的对齐方式
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;
以下是我们可以做的事情:
alignof(float*)
returns8,这显然不是我们想要的
alignof(array)
returns 16,这正是我们想要的,但那是编译器扩展; alignof
标准规定的不能用于特定变量。
alignof(decltype(array))
returns 8,这很符合预期,但不是我们想要的。
std::alignment_of
是根据 alignof
实现的,所以没有太大帮助。
我想要一种机制来确认特定变量 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.
此时你能做的最好的事情就是定义一个单独的变量来保持变量的对齐。
C++11 引入了 alignas
specifier to specify the alignment of a variable, and the alignof
operator 来查询类型的默认对齐方式。但是,我看不到任何方法来对齐特定变量。让我们来看下面这个简单的例子:
alignas(16) float* array;
以下是我们可以做的事情:
alignof(float*)
returns8,这显然不是我们想要的alignof(array)
returns 16,这正是我们想要的,但那是编译器扩展;alignof
标准规定的不能用于特定变量。alignof(decltype(array))
returns 8,这很符合预期,但不是我们想要的。std::alignment_of
是根据alignof
实现的,所以没有太大帮助。
我想要一种机制来确认特定变量 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 ofalignof
to objects and references.
此时你能做的最好的事情就是定义一个单独的变量来保持变量的对齐。