0

以下の構造体に示すように、 と の後に 1 バイトをパディングする必要がvar1ありshortますvar3。これで、合計は 6 になるはずです。これが、Visual Studio で取得している値です。また、データ構造のアライメントに関するウィキペディアでも言及されています。

typedef struct {char var1; short var2; char var3;} Bytes;

しかし、GCC ではサイズが 8 バイトになっています。挙動について教えてください。


こんにちはジャック、

以下の構造で実験を行いました。

typedef struct
{
    char  charVar1;
    short shortVar2;
    char  charVar3;
}tsByte;

printf("\n Sizeo of Byte        : %d", sizeof(Byte));
printf("\n Sizeo of charVar1    : %d", sizeof(Byte.charVar1));
printf("\n Sizeo of shortVar2   : %d", sizeof(Byte.shortVar2));
printf("\n Sizeo of charVar3    : %d", sizeof(Byte.charVar3));
printf("\n Address of charVar1  : %x", &Byte.charVar1);
printf("\n Address of shortVar2 : %x", &Byte.shortVar2);
printf("\n Address of shortVar3 : %x", &Byte.charVar3);

結果は以下の通りです。

Sizeo of Byte        : 8
Sizeo of charVar1    : 1
Sizeo of shortVar2   : 2
Sizeo of charVar3    : 1
Address of charVar1  : 4007e90
Address of shortVar2 : 4007e92
Address of shortVar3 : 4007e94

通常、構造体が配列の要素として使用される場合、(そのすべてのメンバーの) 適切な配置を確保するために、構造体の末尾にパディングが必要です。しかし、最後の要素のパディングと少し混乱しています。「最後の要素」のパディングが 8/16/32 ビット コントローラー アーキテクチャに基づいているか、最大のメンバー サイズに基づいているか (ここでは短い)。

Visual Studio では、最大のメンバー サイズに基づいているため、サイズが 6 バイトになっているように感じます。一方、gcc コンパイラはコントローラー アーキテクチャに基づいており、私は 32 ビット コントローラーを使用しているため、4 バイト メモリに対応しています。このため、gcc コンパイラでは 8 バイトです。間違っている場合は修正してください。

4

3 に答える 3

1

コンパイラ間の違いを調べるには、もう少しコードを書く必要があります。たとえば、次のようなコード フラグメントを試してください。

    // define a structure
    typedef struct {char var1; short var2; char var3;} Bytes;

    // allocate storage for the structure
    Bytes data;

    // tell me stuff about that structure
    printf("\nsizeof Bytes=%d, sizeof var1=%d, sizeof var2=%d, sizeof var3=%d",
         sizeof(data), sizeof(data.var1), sizeof(data.var2), sizeof(data.var3));

Eclipse/Microsoft C コンパイラでは、次のようになりました。

    sizeof Bytes=6, sizeof var1=1, sizeof var2=2, sizeof var3=1

では、なぜ Bytes=6 なのに sizeof vars の合計が 4 になるのでしょうか? これは次のように答えられます。

    printf("\naddrof var1=%08x", &data.var1);
    printf("\naddrof var2=%08x", &data.var2);
    printf("\naddrof var3=%08x", &data.var3);

生成するもの:

    addrof data=0012ff40
    addrof var1=0012ff40
    addrof var2=0012ff42
    addrof var3=0012ff44

そのため、var1 はchar2 バイトを使用しますが、Microsoft C コンパイラは K&R によって文書化されている ANSI C を実装しています!!

GCC を使用して同様のコードを実行し、struct Bytes.

于 2013-08-02T18:57:40.517 に答える
0

特定の配置が必要な場合は、いつでも使用できます#pragma pack

また、他の人がすでに指摘しているように、sizeof()演算子と標準 Coffsetof()マクロを使用して、構造体定義、コンパイラ、およびアライメント設定の特定の組み合わせの実際のアライメントを決定できます。

于 2013-08-05T04:52:47.927 に答える
0

以下の構造に示すように、'var1' の後に 1 バイトをパディングする必要があり、構造内で short が使用されているため、'var3' の後にもう 1 バイトパディングします。これで、合計は 6 になるはずです。

違う。C 言語は、合計サイズがどうあるべきかを規定していません。これは実装定義です。コンパイラは、必要に応じて、メンバー間または構造体の末尾にパディング バイトを自由に追加できます。パディングを追加しない、メンバーを 2 バイトまたは 4 バイト境界に揃える、またはまったく別の方法を選択する場合があります。これらの動作はすべて C 標準で許可されています。

異なるコンパイラが異なる値を生成するという事実は、すべてのコンパイラが同じではないことを示しています。どちらのコンパイラも、この点で C 標準に準拠しています。

于 2013-08-02T19:24:19.393 に答える