2016-02-12 2 views
6

を尊重していないキーワードです。しかし、私はW Sの束を割り当てるしようとすると、その後、私の驚きに、彼らは64バイトにアライメントが合っていないが、実際には16バイトが整列:alignasは私がキャッシュ境界上の私のタイプをoveralignしたいので、私は<code>alignas</code>を使用

#include <iostream> 
#include <iomanip> 
#include <unordered_map> 

struct alignas(64) W { }; 

int main() { 
    std::unordered_map<int, int> offset; 

    for (int i = 0; i < 1000; ++i) { 
     auto w = new W; 
     offset[(uintptr_t)w % 64]++; 
    } 

    for (const auto& p : offset) { 
     std::cout << p.first << ' ' << p.second << '\n'; 
    } 
} 

収量:上

0 250 
16 250 
32 250 
48 250 

いくつかのコンパイル(gcc 4.8.2、gcc 5.2.0、clang 3.7.1)。どうしたの?私は整列するように言った、なぜそれは整列していないのですか?

+5

["オーバーライドされた型がサポートされているかどうか(\ [basic.align \])。"](http://eel.is/c++draft/expr.new#1)。 [CWG issue 2130](http://wg21.link/cwg2130)も参照してください。 –

+1

@ T.C。それは答えに違いないようです。 – NathanOliver

+0

@ T.C。実装がそれをサポートしているかどうか(明らかにgccもclangもありません) – Barry

答えて

3

これはうまくここで回答されていますhttps://stackoverflow.com/a/16510895

基本的には:new(少なくともその通常の使用では)唯一newへのすべての呼び出しのための一定の最大のアライメント(alignof(std::max_align_t))を保証します。

2

他の答えは、既存の制限について説明しているという意味では正しいですが、私は物事が良くなると指摘したいと思います。

T.C.コメントでは、これは言語の長年の欠点でした。これを修正するためにthe WG effortのようなlooksがあると、C++ 17(これは機能完了状態になったばかりです)の解決につながりました。したがって、その標準にコンパイルするとき、std::align_val_tのオーバーロードがnewの新しいものを使用して、動的割り当てによって最終的にオーバーアライメントが尊重されます。したがって、バリーの問題を解決する!必要な新しい足場の量を考えると

は、私はこれが標準の以前のバージョンにバックポートされません推測、これだけの基本的なアライメントを持つタイプのために充足彼らの動的割り当てについての古い警告は、おそらく真のままになります。

関連する問題