2015-09-06 25 views
5

構造体をRustの16バイト境界に揃える必要があります。 repr attributeを使用してアラインメントに関するヒントを示すことは可能ですが、この正確な使用例はサポートしていません。構造体を指定されたバイト境界に揃えるにはどうすればよいですか?

私が達成しようとしているものの機能テストは、このような

assert_eq!(mem::align_of::<Foo>(), 16); 

または代わりにそのタイプFoo

println!("{:p}", Bar::new().baz); 

は常にA印刷さbazようなフィールドを持つ構造体であるBar 16で割り切れる数。

これは現在Rustで可能ですか?回避策はありますか?

+1

ヒープ内の構造体を特定の位置合わせにしたいとしますか?私はスタックに割り当てられた型の整列を認識していませんが、不安定な['allocate'](http://doc.rust-lang.org/std/rt/heap/fn.allocate.html)には整列があります引数。 – Shepmaster

+1

また、パッキングは整列の減少と言います。構造体のメンバ*を常に特定の位置に配置する必要があると言っていますか?いくつかのサンプルコード、ASCIIアートのメモリダイアグラム、またはあなたがこれを行う必要がある理由を説明する文章で質問を補強し、私よりも賢明な人すべてがあなたを助けることができます。^_^ – Shepmaster

+0

フィードバックのおかげで@Shepmaster!私は一般的に整列していたが、はい、私の具体的なユースケースはスタックです。私は質問を明確にするように更新します。 –

答えて

10

アライメントを現時点で直接指定する方法はありませんが、間違いなく有用であることは間違いありません。それはissue #33626とそのRFC issueによってカバーされています。

ある種Tのアラインメントはサイズゼロを有するタイプ[T; 0]のフィールドを含めることであるので、それ以外の場合の動作に影響しないであろうほど大きくなるように、いくつかの構造体Fooのアライメントを強制的に回避策電流構造体、例えばstruct Foo { data: A, more_data: B, _align: [T; 0] }

一晩では、これは、そのサイズ(十分に2の次のべき乗)に等しいアライメントを持つため、夜間にSIMDタイプと組み合わせて、特定のハイアライメントを得ることができます。

#[repr(simd)] 
struct SixteenBytes(u64, u64); 

struct Foo { 
    data: A, 
    more_data: B, 
    _align: [SixteenBytes; 0] 
} 
+0

構造体の開始点が既知の配置を持つ場合、フィールドは常に開始点から固定のオフセットを持つため、静的にのみ配置できます。したがって、このトリックは実際にはフィールドが構造体の順序に関係なく機能します。 – huon

+0

私はそれを知らなかった - ありがとう。したがって、 '(&struct + offset)%desired_alignment == 0'を要求するのではなく、' struct%desired_alignment == 0 && offset%desired_alignment == 0を保証しますか?それはひどく無駄に思えますが、私は理由があるに違いないと確信しています。 – U007D

関連する問題