2010-12-14 15 views
5

コードの行はここ:)千個の言葉の価値がある、私の問題は、次のとおりです。C++メモリアライメント質問

/* Platform specific 16-byte alignment macro switch. 
    On Visual C++ it would substitute __declspec(align(16)). 
    On GCC it substitutes __attribute__((aligned (16))). 
*/ 
#define ALIGN_16 ... 

struct ALIGN_16 A {...}; 

A* ptr = new A; 
A* ptr2 = new A[20]; 

assert(size_t(ptr) % 16 == 0); 

for (int i=0; i<20; ++i) 
    assert(size_t(ptr2+i) % 16 == 0); 

assert(sizeof(A) % 16 == 0); 

は、私はすべてのアサーションがSSEをサポートしているプラ​​ットフォーム上で合格することを期待することはできますか?ありがとうございました。

EDIT。部分的な答え。私はVS2008、GCCとICCでいくつかのテストをしました。 MSコンパイラは、ptrptr2の両方を整列させましたが、GCCとICCは、アライメントに失敗しました。ptr2

+0

なぜ20の配列:gcc-4.3.2に、それは次のように実装されていますとして? – John

+0

ちょうど私の頭の外。アレイのすべての要素が整列していれば、私はさまよっていました。 – watson1180

+2

適切に割り当てられた配列の要素は、問題の型に対して適切に整列されるように標準によって保証されています。しかし、その整列は実装の詳細であり、理論的には1バイト(つまり、パックされた整列)になる可能性があります。 –

答えて

4

Is there any guarantee of alignment of address return by C++'s new operation?

は、言い換えれば、あなたはそれが動作する必要があることを、あなたの仮定を正当化するために、標準を使用することができますが、実際には、それはあなたの顔に爆破します。

doublesnewで割り当てられていませんでした。

std::aligned_storage<Length, Alignment> 

常に正しく限り整合されることが保証される。

+0

新しいコンパイラはどうですか? GCC 4.xxとVS 2008? – watson1180

+1

16バイトのアライメントを 'new'または' malloc'で提供するコンパイラについてはわかりません。つまり、実際にはアサートは失敗します。 – jalf

+0

@ jalf、そうです、それは私が考えたものです。 C++ 0xでは「サポートされている」と仮定していますが、HeapAllocは間接的に8バイトを保証していると考えています(デフォルトのパッキングオプションはWindowsデータ構造の8バイトアライメントです)。 – MSN

1

C++ 0Xは([meta.type.synop]20.7.6.6他の変換に)新しい構築物を提供します私は思い出します。

2番目のパラメータはオプションで、可能な限り厳密な要件が可能です(正確には安全ではありませんが、試してみるとよりコンパクトにパックできます)。

bugsのほかに、コンパイラは要件を満たすためにバインドされています。 C++ 0xがない場合、これはtr1名前空間またはBoostにあります。

あなたはあなたの特定のコンパイラは、この要求:)

注意を尊重しないことをテストすることができる唯一の一つだね:

template<std::size_t _Len, std::size_t _Align = /**/> 
struct aligned_storage 
{ 
    union type 
    { 
    unsigned char __data[_Len]; 
    struct __attribute__((__aligned__((_Align)))) { } __align; 
    }; 
}; 
+0

オブジェクトは 'new'で割り当てられますが、(通常)特定のアラインメント要件を遵守しません。 (ほとんどの場合、8バイトの整列されたメモリが得られます) – jalf

+0

@jalf:しかし、標準では、 'new'が適切に整列されたメモリを返すことを要求しています(3.7.4.1 [basic.std.dynamic私が*を理解しないと、基本的な位置合わせの必要条件(3.11)*と3.11 [基本的なもの]を持つ完全なオブジェクト型のポインタに変換することができます。align = 2 * *基本的な配置は、すべてのコンテキストで実装がサポートする最大の配置よりも小さいか等しい位置合わせで表されます。これはalignof(std :: max_align_t)(18.2)に等しくなります。* –

+0

...したがって'new'が8バイトの整列した値を返すだけで、' std :: max_align_t'が8よりも優れているとすれば、実装は不適合です。 –