- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
如果我定义一个具有特定对齐要求的简单类型,该类型的 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 发出警告,它忽略了 std::vector
(英特尔编译器)的模板参数上的属性太愚蠢了,无法理解 alignas
,但如果我改用 __declspec(align(32))
,它的行为就像 clang)。两者都创建触发断言的代码。
那么,这是正确的行为还是 clang(和 icpc)的错误以及 gcc 的问题?
编辑回答评论中提出的一个问题:如果我定义
typedef typename std::aligned_storage<sizeof (avx_point),
alignof(avx_point)>::type avx_storage;
我明白了
sizeof (avx_storage) == 32;
alignof(avx_storage) == 32;
但是 std::vector<avx_storage>
仍然无法为 clang 和 gcc 对齐第一个元素(因此也无法对齐所有其他元素)(这次没有警告)。因此,这些实现显然存在两个问题:首先,std::allocator<type>
甚至忽略了第一个元素的任何对齐要求(非法?),其次,没有应用填充来确保后续元素的对齐。
–––––––––––
编辑 有一个关于如何获得适合 SSE/AVX 操作对齐的内存的 related, more practical question。相反,我想知道 std::vector<>
(或 std::allocator<>
)是否不应该遵守 C++ 标准(截至 2011 年)的 alignas
。其他问题的答案都不是这个问题的合适答案。
最佳答案
first, that std::allocator ignores any alignment requirements even for the first element (illegal?)
我远不是分配器方面的专家,但不幸的是,在我看来,这是合法行为。更准确地说,分配器可能会忽略请求的对齐。事实上,[allocator.requirements],17.6.3.5/6 状态:
If the alignment associated with a specific over-aligned type is not supported by an allocator, instantiation of the allocator for that type may fail. The allocator also may silently ignore the requested alignment.
您可以编写自己的分配器来为您提供对齐的内存。我以前在工作中这样做过,但不幸的是,出于版权原因,我不能透露代码 :-( 我只能说,这是显而易见的事情:它基于 _aligned_malloc
和 _aligned_free
(这是 Microsoft 的扩展)。或者您可以在 Google 上搜索“对齐的分配器”,然后会出现一些选项,其中之一是
https://gist.github.com/donny-dont/1471329
我强调,我不是这个对齐分配器的作者,而且我从未使用过它。
更新
上面的对齐分配器适用于 Visual Studio/Windows,但它可以用作在其他平台上实现对齐分配器的基础。您可以使用 posix memalign
函数族或 C11 函数 aligned_alloc
。
参见 this发布。
关于c++ - std::vector 应该尊重 alignof(value_type) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16425359/
这个问题在这里已经有了答案: Passing by value vs const & and && overloads (3 个答案) 关闭 8 年前。 为什么push_back的函数签名如下? v
我可以在 C++ 中进行这样的参数解包吗?这段代码无法编译,但我认为这是可能的。 template void foo(Container& container, Args&&... args){
我正在用 C++11 实现自定义容器的迭代器 我收到以下错误: no type named 'value_type' in 'struct std::iterator_traits::seq_read
我正在尝试使用以下代码从容器中提取 value_type。 //CustomTraits.h template struct has_push_back : std::false_type {}; t
我正在尝试定义迭代器包装器的 value_type,它取消引用包装迭代器的 value_type。 对于具有作为实际指针的 value_type 的迭代器,这是微不足道的,但我也需要它为某些“类指针”
我试图了解何时实际使用了 iterator::value_type。 因为,迭代器的所有运算符,似乎只使用iterator::pointer 和iterator::reference。 问题 iter
在我的类(class)里,我有一个成员: std::vector memory_; 现在我想要一个 fnc 返回内存的第一个元素中的内容,但我不想将 std::string 指定为返回类型,以防以后我
在他今年 Going Native 的主题演讲中 The Essence of C++ (转到 40:30)Bjarne Stroustrup 给出了以下代码示例: template vector*>
我正在为自定义容器编写范围构造器: MyContainer(const InputIterator& first, const InputIterator& last,
首先,这是我的例子: SymmetricMatrix, int> a; SymmetrixMatrix, int> b; SymmetricMatrix, double> c; SymmetricMa
对于任何可取消引用的类型,我将如何实现以下目标? 我发现我当前的解决方案缺乏,因为我需要为我希望它使用的每种类型做一个类模板特化: template struct get_value_type {
应该如何使用标准容器的 value_type? 我试着像这样使用它: #include using namespace std; template class TSContainer { priv
STL 通常这样定义输出迭代器: template class insert_iterator : public iterator { // ... 为什么输出迭代器要定义 value_typ
我有以下两个函数用于将 std 容器转换为字符串以进行日志记录。 template std::string LOG_COLLECTION(const TCollection& collection)
我有一个在 typename ContainerType 上参数化的函数模板,它接受一个 const ContainerType& 参数。它将容器内的每个元素转换为其他类型,并(当前)返回转换后类型的
我想编写一个类,将一对迭代器作为构造函数的参数,但我不知道如何在这些迭代器的 value_type 不匹配时在编译时引发错误一个预期的类型。这是我尝试使用 typeid 的结果: #include
我正在写一个序列化和反序列化方法,我在反序列化的实现中遇到了一个问题:我不能new一个value_type,这实际上是一个Skill*。 template static istream &DeSer
给定一个容器,例如 std::list 或 std::vector,我想在我事先不知道容器(std::list 或 std::vector)的情况下分别生成一个新类型 std::list 或 std:
假设我声明 std::vector> .可能发生的更糟情况是什么?我运行了它,似乎没有遇到任何内存错误。 最佳答案 它会导致未定义的行为。对于像 vector 这样的分配器感知容器,标准在表 99 中
我不明白这个神秘的错误消息,但我得到了 30 个 `'value_type' : is not a member of 'TextFileLineBuffer'` 当我在 VC++ 6 中编译以下代码
我是一名优秀的程序员,十分优秀!