2

私のコンパイラでは、適切なデータ アクセスを確保するために、メモリ アラインされた構造宣言が必要です。私は他のいくつかの構造で構成されるトップ構造を持っています。最上位構造が 32 バイト境界に整列されていることを確認するだけで十分ですか、それとも各構造が 32 バイト境界に整列されていることを確認する必要があります。コード スニペットは以下のとおりです。

typedef struct {
   int p;
   int q;
   char n;
} L;

typedef struct {
   int c;
   int d;
   char e;
   L    X2[13];
} B;

typedef struct {
   int a;
   int b;
   B   X1[10];
} M;

正しいデータ アクセスを確保するには、すべての構造体が適切にメモリ アラインされていることを確認する必要がありますか。

4

3 に答える 3

2

アプリケーションで特定のレイアウトが必要になる場合がありますが、この場合、それがコンパイラの要件 (または、より正確にはコンパイラのターゲット アーキテクチャ) である場合、それらの要件が満たされていることを確認するのはコンパイラの責任です。

ターゲットの要求に応じてコンパイラが自然に強制する以外の位置合わせが必要な場合は、パッキングと位置合わせのためのコンパイラ固有のディレクティブが必要になります。ただし、そのようなディレクティブを適用して間違うと、コンパイラーに処理させるよりも、アラインメント違反を引き起こす可能性がはるかに高くなります。独自のパディング メンバーを追加して整列しようとすると、機能する可能性がありますが、不要であり、コンパイラは独自の追加のパディングも挿入する可能性があります。

ポイントは、コンパイラが安全かつ効率的にアドレス指定できないメンバーを含む構造体を生成しないことです。後続のメンバーがアドレス可能であることを確認するために、メンバー間に必要なパディングが挿入されます。

動作しないと思われる場合は、リンカーにマップ ファイルを出力させ (まだ出力されていない場合)、これらのシンボルのアドレスをチェックして、正しい位置合わせを確認してください。生成された構造体のサイズも見てください。それらのいくつかは、それらの部分の合計よりも大きい場合があります。これは、パディングを挿入することによってコンパイラーがアラインメントを強制することです。

于 2012-07-17T20:27:24.237 に答える
0

使用できる場合、C11 には、アプリケーション (またはアーキテクチャ、またはパフォーマンス) が必要な場合の調整ステートメントがあります: http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29

  • アライメント指定 (_Alignas 指定子、alignof 演算子、aligned_alloc 関数、ヘッダー ファイル)

GCCには確かに拡張機能もあります。

于 2012-07-17T21:04:26.823 に答える
0

自然な位置合わせを使用する場合は、フィールドを並べ替えて、自然な単語サイズに手動でパディングする必要があります。移植性は保証されていませんが、特定のプロセッサではこれを行うことができます (組み込みの世界では珍しいことではありません)。sizeof(int) が 4 の場合、サブ構造体にパディングを追加して、配列内のアライメントを確保する必要があります (コンパイラによって追加された「秘密の」パディングを回避することが目標だと思いますか?)。例えば ​​:

typedef struct {
   int p;
   int q;
   char n;
   char pad[3];
} L;

typedef struct {
   int c;
   int d;
   char e;
   char pad[3];
   L    X2[13];
} B;

typedef struct {
   int a;
   int b;
   B   X1[10];
} M;

通常、構造内に「隠れた」アライメントは発生しません。

于 2012-07-24T17:25:27.527 に答える