2010-11-30 5 views
10

私は48ビットまでのビットフィールドの構造体を持っています。 GCCでは、これは正しく6バイト構造になりますが、MSVCでは構造が8バイトになります。 MSVCに構造体を適切にパックするような方法を見つけ出す必要があります。これは、相互運用性のため、またメモリが重要な環境で使用されているためです。MSVCのアラインされていないビットフィールドのパッキングを強制する

構造体は、3つの15ビット数、1つの2ビット数、および1ビットの符号で構成されています。 15 + 15 + 15 + 2 + 1 = 48だから理論的には6バイトに収まるはずですよね?

struct S 
{ 
    unsigned short a:15; 
    unsigned short b:15; 
    unsigned short c:15; 
    unsigned short d:2; 
    unsigned short e:1;  
}; 

しかし、sizeof(S) == 8の両方のGCCとMSVCの結果でこれをコンパイルします。これはアラインメントと関係があると思われるので、構造体宣言の前に#pragma pack(1)を使用して、コンパイラにintではなく境界に戻るように指示しました。 GCCでは、this workedであり、結果としてsizeof(S) == 6となる。

ただし、MSVC05では、pack(1)を設定しても、サイズはまだ8になりました! this other SO answerを読んだ後、unsigned charunsigned short eboolに置き換えようとしました。結果はsizeof(S) == です!

dを2つの1ビットフィールドに分割し、それらを他のメンバーの間に詰め込むと、構造体が最終的に正しくパックされていることがわかりました。

struct S 
{ 
    unsigned short a:15; 
    unsigned short dHi : 1; 
    unsigned short b:15; 
    unsigned short dLo : 1; 
    unsigned short c:15; 
    unsigned short e:1;  
}; 

printf("%d\n", sizeof(S)); // "6" 

しかし、それは面倒であり、後に、私は構造体で仕事をしなければならないときに私のために、トラブルの原因となるようDスプリットを持ちます。 MSVCにGCCのようにこの構造体を6バイトにパックする方法がありますか?

答えて

5

フィールドがどのように構造内に配置されるかは、実装によって定義されます。ビジュアルスタジオは連続したビットフィールドを基になるタイプに合わせ、残りのスペースを無駄にします。 (C++ Bit Fields in VS

+0

参考になっていただきありがとうございます。 – Crashworks

+0

優れたリファレンス!私の問題を助けました。(VC++は16ビットのビットフィールドを4バイト構造にしていました。 – nirbruner

0

私はそうは思わないし、実際には正しいMSVCの動作、そして標準から逸脱したGCCだと思う。

AFAIKは、ビットフィールドが基本タイプのワード境界を横切ることを許可していません。

+3

に動作します –

3

"unsigned __int64"型を使用して構造体のすべての要素を宣言すると、sizeof(S)= 8のオブジェクトが生成されますが、最後の2バイトは使用されず、必要な形式でデータが格納されます。あなたには、いくつかの構造の並べ替えを受け入れることができるかどう

あるいは、これは「注意してください。:ビットフィールドは、他のいくつかのマシンではなく上のアロケーション・ユニットにまたがる」9.6.1 /から

#pragma pack(1) 
struct S3 
{ 
    unsigned int a:15; 
    unsigned int b:15; 
    unsigned int d:2; 
    unsigned short c:15; 
    unsigned short e:1;  
}; 
関連する問題