6

私はCで次のネストされた構造体を持っています。(64ビット)

    typedef struct {
        int a;
        int b;
        int c;
        struct {
            int ab;
            long bc;
        }
        int d;
    } Test;

I see that,
a = 4 bytes
b = 4 bytes
c = 4 bytes
padding1 = 4 bytes 
inner structure = 16 bytes ( 4 bytes for ab, 4 bytes padding, 8 bytes for bc)
d = 4 bytes
padding2 = 4 bytes

sizeof(Test)は40バイトを返します。

私の質問:

  1. padding1->なぜこれが4バイトなのですか?これは、内部構造自体を整列させる必要があるためですか?(また、8バイト(長い)または16バイト(内側のサイズ)の境界に揃えられていますか?)

  2. padding2->構造内で行われるアライメントの最大値(8)のため、これは4バイトのパディングですか?

ありがとう、

4

2 に答える 2

7
  1. padding1->なぜこれが4バイトなのですか?これは、内部構造自体を整列させる必要があるためですか?(また、8バイト(長い)または16バイト(内側のサイズ)の境界に揃えられていますか?)

これは、が確実に8バイトに整列できるように、内部structを8バイトに整列させる必要があるためです。long

  1. padding2->構造内で行われるアライメントの最大値(8)のため、これは4バイトのパディングですか?

全体のサイズがstruct8バイトの倍数になるように配置されているため、内部structを8バイトの境界に適切に配置できます。

この特定のケースでは、匿名structメンバーを自立型とは異なる方法で処理できる場合、わずか4バイトのパディングでアライメント要件を満たすことができますstructが、6.7.2.1

14構造体または共用体オブジェクトの各非ビットフィールドメンバーは、そのタイプに適した実装定義の方法で整列されます。

それを禁じます。したがって、のサイズを小さくするにはstruct、プログラマーはそれを再配置し、奇数のintメンバーを内部を超えて移動する必要がありますstruct(または、匿名を経由せずにメンバーを作成int ab;してlong bc;指示します)。Teststruct

于 2012-12-18T06:21:00.097 に答える
0

表示される動作は非常に一般的ですが、パディングはプラットフォームとコンパイラに大きく依存します。

一般に(これはC標準ではありませんが)、コンパイラーは、メモリー・アクセスの数を減らすために、構造体のメンバーを整列させます。64ビットx86の場合、メモリアクセスは常に8バイトをフェッチし、64ビット境界に揃えます。つまり、アドレス0x1010AA45で1バイトにアクセスすると、CPUは実際にはアドレス0x01010AA40で8バイトをメモリからフェッチ(キャッシュ)します。

このようなルールを満たすために、メンバーの長さがNバイトの場合、コンパイラーは通常、Nを2の次の累乗に丸め、メンバーをそのようなサイズまたは64ビットプラットフォームでは8バイトの小さい方に揃えます。ほとんどのコンパイラでは、このようなルールを、#pragmaまたは構成を介して微調整することができます。

コンパイラにはPadding1が追加されていると思います。これは、構造がどれほど大きくても、すべての構造を8バイト境界に揃えるルールがあるためです。または、内部構造が4バイトよりも大きいため、8バイトに揃える必要があるため、これを導入することもできます。

の配列を作成できるため、Padding2struct Testが導入された可能性があります。配列の最初の項目だけでなく、すべての構造が8バイト境界に正しく位置合わせされることを保証するために、最後のパディングが定義されます。

于 2012-12-18T06:48:43.103 に答える