1

次のプログラムを検討してください

#include <cstdio>
#include <stdint.h>

struct Foo
    {
    int32_t a;
    int32_t b;
    int32_t c;
    };

struct Bar
    {
    int32_t a;
    int32_t b;
    int16_t c;
    };

int main()
    {
    printf("sizeof(Foo)=%u\nsizeof(Bar)=%u",sizeof(Foo),sizeof(Bar));
    return 0;
    }

MinGWを使用してコンパイルすると、32ビットシステムと64ビットシステムの両方でsizeof(Foo)= 12とsizeof(Bar)= 12が得られます(16ビット環境ではsizeof(Bar)= 10だと思います)。将来的には、これらの構造のサイズが16になり、64ビット環境での適合性が向上する可能性がありますか?

構造体をファイルに保存していますが、将来的に回避策を追加したくありません。運命の物の構造のレイアウトはおそらく1993年には良い選択でしたが、今日はそうではありませんでした。

4

2 に答える 2

6

構造体のサイズはBar、16ビット環境を使用しているかどうかとはほとんど関係がなく、構造体内のフィールドの配置要件とのみ関係があります。

構造の配置は、一般に、その中のすべてのフィールドの最も制限的な配置と同じです。この場合、int32_t影響を与えるのはタイプの32ビットアライメント要件です。

最後のフィールドは16ビット値であり、その後は何も調整する必要がないため、これは当てはまらないと思うかもしれませんが、間違いです。それらの配列で何が起こるか考えてみてください。

0000  index 0  a      32 bits
0004           b      32 bits
0008           c      16 bits
000a           filler 16 bits
000c  index 1  a      32 bits
0010           b      32 bits
0014           c      16 bits
0018           filler 16 bits

c以下aを正しく位置合わせする必要があるため、後にフィラーが必要であることがわかります。

将来的には、これらのフィールドが正確なビット幅タイプであるという理由だけで、これらのフィールドの配置が変更される可能性はほとんどありません。それらは常に32ビット値であり、おそらく常に32ビットアライメントが必要です。

そうは言っても、将来のある時点で32ビット値を128ビット境界に揃える必要がある実装が見つからないという保証はありません。セクション6.2.8 Alignment of objectsはC11の制御セクションであり、配置がオブジェクトサイズに関連していることを示していないため、この可能性を軽視しているようには見えません。

オブジェクトタイプは、そのタイプのすべてのオブジェクトに配置要件を課します_Align。キーワードを使用して、より厳密な配置を要求できます。

構造体のサイズや配置が変更される可能性を把握したい場合は、関数でsizeofandを使用してメッセージを出力し、正しくない場合は終了することができます。これはフィールド内のコードには影響しませんが、より厳密な配置のコンパイラーに移行する場合に非常に役立ちます。alignofmain

そしてそれはあなたがそれを変えるポイントです(YAGNIを見てください)。考えられるすべての先物を計画する際の問題は、何が起こるかわからないことです:-)

于 2012-08-28T07:34:42.503 に答える
0

未来...今のところあなたは使うことができます#pragma pack(1)

于 2012-08-28T08:17:35.743 に答える