GNU GCC 中 `__builtin_assume_aligned` 的类型变体?
typed variant of `__builtin_assume_aligned` in GNU GCC?
GNU 提供了一个函数 void * __builtin_assume_aligned(void *, int)
,它告诉编译器可以安全地假设函数输入(和返回)的指针按 N
字节对齐。但是,它 returns 一个 void *
,这意味着我必须转换返回的结果,即
float *example = (float *) __builtin_assume_aligned(example_aligned, 64);
或
float *example = std::reinterpret_cast<float *>
(__builtin_assume_aligned(example_aligned, 64));
这两种感觉都像是 C/C++ 风格的方法(即有人用 C 风格的代码编写 C++)。是否有等同于 __builtin_assume_aligned
的 C++,还是我太挑剔了?
正如 kebno 所建议的,模板包装器可以提供帮助:
template<typename T>
T * assume_aligned(T * p, size_t a, int m = 0)
{
return reinterpret_cast<T *>(__builtin_assume_aligned(p, a, m));
}
此外,它可能仅在 a
(和 m
?我从未使用过第三个参数)是常量时才有用,这将进一步允许您检查一些不变量:
template<size_t a, int m = 0, typename T>
T * assume_aligned(T * p)
{
static_assert(a >= alignof(T));
static_assert(is_pow2(a));
return reinterpret_cast<T *>(__builtin_assume_aligned(p, a, m));
}
虽然它不会消除施法的需要,但它会将范围限制在一个位置。
GNU 提供了一个函数 void * __builtin_assume_aligned(void *, int)
,它告诉编译器可以安全地假设函数输入(和返回)的指针按 N
字节对齐。但是,它 returns 一个 void *
,这意味着我必须转换返回的结果,即
float *example = (float *) __builtin_assume_aligned(example_aligned, 64);
或
float *example = std::reinterpret_cast<float *>
(__builtin_assume_aligned(example_aligned, 64));
这两种感觉都像是 C/C++ 风格的方法(即有人用 C 风格的代码编写 C++)。是否有等同于 __builtin_assume_aligned
的 C++,还是我太挑剔了?
正如 kebno 所建议的,模板包装器可以提供帮助:
template<typename T>
T * assume_aligned(T * p, size_t a, int m = 0)
{
return reinterpret_cast<T *>(__builtin_assume_aligned(p, a, m));
}
此外,它可能仅在 a
(和 m
?我从未使用过第三个参数)是常量时才有用,这将进一步允许您检查一些不变量:
template<size_t a, int m = 0, typename T>
T * assume_aligned(T * p)
{
static_assert(a >= alignof(T));
static_assert(is_pow2(a));
return reinterpret_cast<T *>(__builtin_assume_aligned(p, a, m));
}
虽然它不会消除施法的需要,但它会将范围限制在一个位置。