应该std :: vector honor alignof(value_type)?

时间:2013-05-07 17:46:25

标签: c++ c++11 alignment containers

如果我定义一个具有特定对齐要求的简单类型,那么所述类型的std::vector<t>是否应该尊重每个元素的对齐

考虑以下示例

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

我发现对齐要求是由clang 3.2(有或没有-stdlib=libc++)默认(没有任何警告),而gcc 4.8.0发出警告,忽略模板参数{}的属性{1}}(英特尔编译器太愚蠢而无法理解std::vector,但如果我使用alignas代替它,它的行为就像铿锵声)。两者都创建触发断言的代码。

那么,这是正确的行为还是clang(和icpc)的错误以及gcc的问题?

修改 回答评论中提出的问题:如果我定义

__declspec(align(32))

我得到了

typedef typename std::aligned_storage<sizeof (avx_point),
                                      alignof(avx_point)>::type avx_storage;

但是sizeof (avx_storage) == 32; alignof(avx_storage) == 32; 仍然无法对齐clang和gcc的第一个元素(因此也是所有其他元素)(此时没有警告)。因此,实现显然存在两个问题:首先,即使对于第一个元素(非法?),std::vector<avx_storage>也忽略了任何对齐要求,其次,没有应用填充来确保后续元素的对齐。

1 个答案:

答案 0 :(得分:3)

  

首先,即使对于第一个元素(非法?)

,std :: allocator也会忽略任何对齐要求

我远不是分配器专家,但在我看来,不幸的是,这是合法行为。更确切地说,分配器可能会忽略请求的对齐。的确,[allocator.requirements],17.6.3.5 / 6表示:

  

如果分配器不支持与特定的过度对齐类型关联的对齐,则实例化   该类型的分配器可能会失败。 分配器也可以默默地忽略请求的对齐

您可以编写自己的分配器来为您提供对齐的内存。我在工作之前已经这样做了,但不幸的是,出于版权原因,我无法透露代码:-(我只能说,这是显而易见的事情:它基于_aligned_malloc_aligned_free (这是微软的扩展)。或者你可以谷歌“对齐分配器”,并会出现一些选项,其中一个是

https://gist.github.com/donny-dont/1471329

我强调我不是这个对齐的分配器的作者,我从来没有使用它。

<强>更新

上面的对齐分配器适用于Visual Studio / Windows,但它可以用作在其他平台上实现对齐分配器的基础。您可以使用posix memalign函数族或C11函数aligned_alloc

请参阅this帖子。