将缓冲区对齐到N字节边界但不是2N字节边界?

Bee*_*ope 1 c++ assembly c++11

我想分配一些char缓冲区0,以传递给具有特定对齐要求的外部非C++函数.

的要求是,该缓冲器被对齐到N字节1边界,但2N边界.例如,如果N是64,则指向此缓冲区的指针p应满足((uintptr_t)p) % 64 == 0并且((uintptr_t)p) % 128 != 0- 至少在指针具有通常解释的平台上作为转换时的普通地址uintptr_t.

有没有合理的方法来使用C++ 11的标准工具?

如果没有,是否有合理的方法在标准设施2之外执行此操作,这在现代编译器和平台的实践中有效?

缓冲区将传递给外部例程(遵守C ABI但以asm编写).所需的对齐通常大于16,但小于8192.

过度分配或任何其他轻微的资源浪费问题都是完全正确的.我对正确性和可移植性比对浪费几个字节或毫秒更感兴趣.

在堆和堆栈上都能正常工作的东西是理想的,但任何可用的东西仍然相当不错(优先考虑堆分配).


0这可能是用operator new[]malloc或者是一些其他的方法是对准感知:什么是有意义的.

1像往常一样,N是两个人的力量.

2是的,我理解这种类型的答案会导致语言律师变得中风,所以如果你只是忽略了这一部分.

Ken*_*Y-N 5

逻辑上,为了满足"与N对齐,而不是2N",我们对齐2N然后添加N到指针.请注意,这将过度分配N字节.

所以,假设我们想要分配B字节,如果你只是想要堆栈空间alignas,也许可以工作.

alignas(N*2) char buffer[B+N];
char *p = buffer + N;
Run Code Online (Sandbox Code Playgroud)

如果你想要堆空间,std::aligned_storage可能会这样做:

typedef std::aligned_storage<B+N,N*2>::type ALIGNED_CHAR;
ALIGNED_CHAR buffer;
char *p = reinterpret_cast<char *>(&buffer) + N;
Run Code Online (Sandbox Code Playgroud)

我没有测试过,但文档表明应该没问题.

  • 我不知道标准是什么,但Visual C++ 2017声明它支持[最多8198字节](https://docs.microsoft.com/en-gb/cpp/cpp/align-cpp).GNU`g ++`似乎[支持128字节](https://www.mail-archive.com/gcc-bugs@gcc.gnu.org/msg487113.html). (2认同)