4

次の形式でいくつかのデータを処理する必要があります。

typedef struct{
    unsigned n1 : 12;
    unsigned n2 : 12;
    unsigned n3 : 12;
    unsigned n4 :  1;
    unsigned n5 : 35;
} data;

合計で最大9バイトになるようにしました。
しかし、そうではありません。その構造体の9バイトをファイルに書き込んで読み戻すと、すべてのデータが復元されず、sizeof(data)16が返されます。
ここでの問題は何ですか。

4

4 に答える 4

8

問題は、効率上の理由から、コンパイラーによっていくつかのパディングが追加されていることです。

この動作はオーバーライドできます。

gccでこれを行う方法については、GCCでの強制アライメントを参照してください。

Visual C ++でこれを行う方法については、VisualC++での強制的な配置を参照してください。

于 2011-05-26T17:42:42.793 に答える
1

構造体の長さは9バイトです。コンパイラは、キャッシュをより使いやすくするために、16バイトにパディングします。これは、コンパイラ固有のディレクティブ/キーワードを使用してオフにすることができます(一般的にはお勧めしません)。データ構造のアライメントを参照してください。

于 2011-05-26T17:45:50.763 に答える
1

gcc固有の強制アライメントを使用できます:

typedef struct{
    unsigned n1 : 12;
    unsigned n2 : 12;
    unsigned n3 : 12;
    unsigned n4 :  1;
    unsigned n5 : 35;
} data __attribute__((__packed__));

読む: http: //gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Type-Attributes.html

于 2011-05-26T17:46:15.893 に答える
0

これは、36ビットコンピューターで非常にうまく機能します。あなたはそれがあなたが持っているものであるかどうか私たちに言うのを忘れました...

より一般的な32ビットマシンでは、9バイトのアラインメントを使用して実装するのは非常に困難です。これらの構造体の配列を作成する場合、アドレスが0を法とするオブジェクトとアドレスが9を法とするオブジェクトのフィールドにアクセスするには、異なるコードが必要になります。

最初の3つのフィールドの12ビットはunsigned、アドレスに応じて異なるsから収集する必要があります。

ビットアドレス指定付きのハードウェア(または36ビットCPU)がない限り、他の回答のパッキングディレクティブがここで機能する可能性はほとんどありません。

于 2011-05-26T18:42:19.190 に答える