Wal*_*ter 7 c++ containers alignment c++11
如果我定义一个具有特定对齐要求的简单类型,那么std::vector<t>所述类型的a是否应该遵循每个元素的对齐?
请考虑以下示例
typedef std::array<double,3> alignas(32) avx_point;
std::vector<avx_point> x(10);
assert(!(std::ptrdiff_t(&(x[0]))&31) && // assert that x[0] is 32-byte aligned
!(std::ptrdiff_t(&(x[1]))&31)); // assert that x[1] is 32-byte aligned
Run Code Online (Sandbox Code Playgroud)
我发现对齐要求是默认(没有任何警告)被clang 3.2(有或没有)违反-stdlib=libc++,而gcc 4.8.0发出一个警告,它忽略了模板参数的属性std::vector(intel编译器太愚蠢了解alignas,但如果我使用__declspec(align(32))它,它的行为就像clang).两者都创建触发断言的代码.
那么,这是正确的行为还是clang(和icpc)的错误以及gcc的问题?
编辑 以回答评论中提出的问题:如果我定义
typedef typename std::aligned_storage<sizeof (avx_point),
alignof(avx_point)>::type avx_storage;
Run Code Online (Sandbox Code Playgroud)
我明白了
sizeof (avx_storage) == 32;
alignof(avx_storage) == 32;
Run Code Online (Sandbox Code Playgroud)
但是std::vector<avx_storage>仍然无法对齐clang和gcc的第一个元素(因此也是所有其他元素)(这次没有警告).因此,实现显然存在两个问题:首先,std::allocator<type>即使对于第一个元素(非法?),也忽略了任何对齐要求;其次,没有应用填充来确保后续元素的对齐.
首先, std::allocator 忽略任何对齐要求,即使是第一个元素(非法?)
我远不是分配器方面的专家,但不幸的是,在我看来,这是合法行为。更准确地说,分配器可能会忽略所请求的对齐。事实上,[allocator.requirements], 17.6.3.5/6 指出:
如果分配器不支持与特定过度对齐类型相关联的对齐,则该类型的分配器的实例化可能会失败。分配器也可能默默地忽略所请求的对齐。
您可以编写自己的分配器来为您提供对齐的内存。我以前在工作中已经这样做过,但不幸的是,出于版权原因,我不能透露代码:-( 我能说的就是显而易见的事情:它基于_aligned_malloc和_aligned_free(它们是 Microsoft 扩展)。或者你可以谷歌搜索“对齐分配器”,会出现一些选项,其中之一是
https://gist.github.com/donny-dont/1471329
我强调,我不是这个对齐分配器的作者,而且我从未使用过它。
更新
上面的对齐分配器适用于 Visual Studio/Windows,但它可以用作在其他平台上实现对齐分配器的基础。您可以使用 posixmemalign系列函数或 C11 函数aligned_alloc。
请参阅这篇文章。