2009-03-10 14 views
5

同じデータ型のビットフィールドのサイズが混合型の データ型よりも小さい理由を知りたいのは興味深いです。同じデータ型のビットフィールドのサイズが混合データ型のビットフィールドと比較して小さい理由

struct xyz 
{ 
    int x : 1; 
    int y : 1; 
    int z : 1; 
}; 


struct abc 
{ 
    char x : 1; 
    int y : 1; 
    bool z : 1; 
}; 

はsizeof(XYZ)= 4 はsizeof(ABC)= 12

私はVS 2005を使用しています、64ビットのx86機。

ビットマシン/コンパイラレベルの回答は素晴らしいでしょう。

答えて

4

アライメント。

あなたのコンパイラは、あなたのアーキテクチャに合った方法で変数を整列させます。あなたのケースでは、charint、およびboolは異なるサイズなので、ビットフィールドのヒントではなくその情報になります。

this questionにいくつかの議論がありました。

解決策は、#pragmaディレクティブまたは__attributes__コンパイラにアラインメントの最適化を無視するように指示することです。

+1

ただし、ビットフィールドには実際に位置合わせの要件はありません。 –

+0

いいえ、コンパイラはそれらをパックする義務はありません。 – greyfade

+0

ISO14882:2003、§9.6、パラグラフ1を参照してください。 – greyfade

3

C標準(1999バージョン、§6.7.2.1、102ページ、ポイント10)が、これは言う:

実装は ビットフィールドを保持するのに十分な大きさの任意のアドレス指定可能な記憶部を割り当てることができます。十分なスペースが残っている場合は、構造内の別のビットフィールドの直後にあるビットフィールドは、同じユニットの隣接ビットにパックされます。

フィールドのタイプの影響を受けるようにするための言葉遣いはありません。したがって、私はこれがコンパイラのバグであると結論づけます。

gccは、Linuxの場合、32ビットマシンと64ビットマシンの両方で4バイトの構造体を作成します。私はVSを持っていないので、それをテストすることはできません。

+1

C++ 03、§9.6、パラグラフ1は、 "クラスオブジェクト内のビットフィールドの割り当ては実装定義です。ビットフィールドのアライメントは実装定義です。ビットフィールドはいくつかのアドレス可能なアロケーションユニットにパックされています。 maheshはC++コンパイラを使用しているようです。 – greyfade

+0

一方、彼はこれをC++だけでなくCの質問としてタグ付けしました。私はCとC + +の答えが異なると思います。 –

+0

あなたはISO C99標準から引用しているので、私はこれを "バグ"と主張することには注意が必要です。 MSVC++はC99への準拠を主張していません。 ISO C90/ANSI C89に対応しています。 – Clifford

0

コンパイラのバグやコードエラーです。 構造体に割り当てられたすべてのビットは、常にsizeofの最大データ型を定義しようとします。例: 構造体xyzでは、最大のデータ型は4、すなわちintです。 同様の方法で、2番目の構造体abcのデータ型の最大サイズはintの場合4です。我々は、以下のような構造の変数を変更した場合のよう

: 構造体ABCチャー {:1。 char b:1; bool c:1; };

sizeof(abc)は1ではありません4.サイズの最大データ型は1であり、すべてのビットが1バイトのcharに収まるためです。

構造内のデータ型を変更することによって、さまざまなテストを実行できました。古い構造に基づいて出力用

リンク:私が上に定義された構造に基づいて出力用http://codepad.org/6j5z2CEX

リンク ログイン: 訪問http://codepad.org/fqF9Ob8W

のsizeof構造我々は適切に使用して構造体をパックしなければならないため、このような問題を回避するには#pragma pack macro。

関連する問題