構造体または共用体のメンバーの宣言子に加えて、構造体宣言子は、"ビット フィールド" と呼ばれる指定されたビット数にすることもできます。その長さは、コロンによってフィールド名の宣言子から設定されます。 ビット フィールドは整数型として解釈されます。
構文
struct-declarator
=
declarator
type-specifier
declarator
opt :
constant-expression
constant-expression
は、フィールドの幅 (ビット単位) を指定します。 declarator
の type-specifier
は、unsigned int
、signed int
、または int
である必要があります。constant-expression
は負でない整数値である必要があります。 値がゼロの場合、宣言には declarator
がありません。 ビット フィールド、ビット フィールドへのポインター、およびビット フィールドを返す関数の配列は使用できません。 省略可能な declarator
はビット フィールドの名前を指定します。 ビット フィールドは構造体の一部としてしか宣言できません。 アドレス演算子 (&
) は、ビット フィールド コンポーネントに適用できません。
名前のないビット フィールドは参照できず、実行時の内容は予測できません。 これらはアラインメントのために "ダミー" フィールドとして使用できます。 幅が 0 として指定された、名前のないビット フィールドは、struct-declaration-list 内でそれに続くメンバーのストレージが、int
境界で開始されることを保証します。
ビット フィールドのビット数は、基になる型のサイズ以下である必要があります。 たとえば、次の 2 つのステートメントは正しくありません。
short a:17; /* Illegal! */
int long y:33; /* Illegal! */
次の例では、screen
という名前の構造体の 2 次元配列を定義します。
struct
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];
配列には 2,000 の要素が含まれます。 各要素は、icon
、color
、underline
、および blink
の 4 つのビット フィールド メンバーを含む個別の構造体です。 各構造体のサイズは 2 バイトです。
ビット フィールドには、整数型と同じセマンティクスがあります。 同じ基本型の変数が使用される場合とまったく同じように、式でビット フィールドが使用されます。 ビット フィールドにあるビット数は関係ありません。
Microsoft 固有の仕様
int
として定義されたビット フィールドは、 signed
として扱われます。 ANSI C 標準への Microsoft 拡張機能を使用すると、ビット フィールドに対して char
型と long
型 ( signed
、 unsigned
両方) が許可されます。 基本型が long
、short
、または char
(signed
または unsigned
) である名前のないビット フィールドは、基本型に適した境界に強制的に配置されます。
ビット フィールドは、整数内で最下位ビットから最上位ビットへと割り当てられます。 次のコードでは、
struct mybitfields
{
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
} test;
int main( void )
{
test.a = 2;
test.b = 31;
test.c = 0;
return 0;
}
test
のビットは次のように配置されます。
00000001 11110010
cccccccb bbbbaaaa
8086 ファミリのプロセッサでは、整数値の下位バイトを上位バイトの前に格納するため、0x01F2
という整数は、0xF2
の後に 0x01
が続く形で物理メモリに格納されます。
ISO C99 標準では、ビット フィールドが 2 つのストレージ インスタンスをまたげるかどうかを実装で選択できます。 たとえば、合計で 64 ビットになるビット フィールドが格納される、次の構造体を考えてみます。
struct
{
unsigned int first : 9;
unsigned int second : 7;
unsigned int may_straddle : 30;
unsigned int last : 18;
} tricky_bits;
標準 C 実装では、これらのビット フィールドを 2 つの 32 ビット整数にパックできます。 tricky_bits.may_straddle
は、1 つの 32 ビット整数では 16 ビットとして、次の 32 ビット整数では 14 ビットとして格納される場合があります。 Windows ABI 規則では、ビット フィールドを 1 つのストレージ整数にパックし、ストレージ ユニットにはまたがりません。 上記の例では、Microsoft コンパイラに各ビット フィールドが格納されるため、1 つの 32 ビット整数に完全に収まります。 この場合、first
と second
は 1 つの整数に格納され、may_straddle
は 2 番目の整数に格納され、last
は 3 番目の整数に格納されます。 sizeof
演算子は、tricky_bits
のインスタンスに対して 12
を返します。 詳細については、「構造体メンバーの埋め込みと配置」を参照してください。
Microsoft 固有の仕様はここまで