Bit-fields
明示的なビット幅を持つメンバーを宣言します。隣接するビットフィールドメンバーは、個々のバイトを共有し、またまたがるようにパックされる場合があります。
ビットフィールド宣言は、以下の struct または union メンバー宣言であり、次の 宣言子 を使用します:
識別子
(オプション)
:
幅
|
|||||||||
| identifier | - | 宣言されるビットフィールドの名前。名前は任意:無名ビットフィールドは指定されたビット数のパディングを導入する |
| width | - | ゼロ以上かつ基底型のビット数以下の整数 定数式 。ゼロより大きい場合、このビットフィールドが占有するビット数となる。値ゼロは無名ビットフィールドにのみ許可され、特別な意味を持つ:クラス定義内の次のビットフィールドが割り当て単位の境界から開始することを指定する。 |
目次 |
説明
ビットフィールドは以下の(場合によっては const 修飾または volatile 修飾された)型のうち1つのみを持つことができます:
-
unsigned
int
, 符号なしビットフィールド用(例:
unsigned
int
b
:
3
;
の範囲は
[ 0 ,7]) -
signed
int
, 符号付きビットフィールド用(
signed
int
b
:
3
;
の範囲は
[- 4,3]) -
int
, 実装定義の符号付き/符号なしを持つビットフィールド用(このキーワードの意味は他のすべての場所での「signed int」を意味する
int
とは異なることに注意)。例えば、
int
b
:
3
;
の値の範囲は
[ 0 ,7]または[- 4,3]となる可能性がある。
|
(C99以降) |
|
(C23以降) |
追加の実装定義型が許容される可能性があります。 ビットフィールドが atomic 型を持つことができるかどうかも実装定義です。 (C11以降) ビットフィールドのビット数( width )は、保持できる値の範囲の上限を設定します:
#include <stdio.h> struct S { // 3ビット符号なしフィールド、 // 許容値は0...7 unsigned int b : 3; }; int main(void) { struct S s = {7}; ++s.b; // 符号なしオーバーフロー printf("%d\n", s.b); // 出力: 0 }
複数の隣接するビットフィールドは、(通常は)まとめてパックすることが許可されています:
#include <stdio.h> struct S { // 通常4バイトを占有: // 5ビット: b1の値 // 11ビット: 未使用 // 6ビット: b2の値 // 2ビット: b3の値 // 8ビット: 未使用 unsigned b1 : 5, : 11, b2 : 6, b3 : 2; }; int main(void) { printf("%zu\n", sizeof(struct S)); // 通常4を表示 }
特別な 名前のないビットフィールド で width をゼロにすると、パディングを分割します:これは次のビットフィールドが次の割り当て単位の先頭から始まることを指定します:
#include <stdio.h> struct S { // 通常8バイトを占有: // 5ビット: b1の値 // 27ビット: 未使用 // 6ビット: b2の値 // 15ビット: b3の値 // 11ビット: 未使用 unsigned b1 : 5; unsigned : 0; // 新しいunsigned intを開始 unsigned b2 : 6; unsigned b3 : 15; }; int main(void) { printf("%zu\n", sizeof(struct S)); // 通常8を出力 }
ビットフィールドは必ずしもバイトの先頭から始まるわけではないため、ビットフィールドのアドレスを取得することはできません。ビットフィールドへのポインタは不可能です。ビットフィールドは
sizeof
および
_Alignas
(C11以降)
(C23以前)
alignas
(C23以降)
(C11以降)
と共に使用することはできません。
注記
以下のビットフィールドの使用法は 未定義動作 を引き起こします:
- offsetof をビットフィールドに対して呼び出すこと。
ビットフィールドの以下のプロパティは 未規定 です:
- ビットフィールドを保持する割り当て単位のアライメント。
ビットフィールドの以下のプロパティは 実装定義 です:
- int 型のビットフィールドが符号付きとして扱われるか符号なしとして扱われるか。
- int 、 signed int 、 unsigned int 、 _Bool (C99以降) および(場合によっては unsigned ) _BitInt ( N ) (C23以降) 以外の型が許可されるかどうか。
|
(C11以降) |
- ビットフィールドが割り当て単位の境界を跨ぐことができるかどうか。
- 割り当て単位内でのビットフィールドの順序(一部のプラットフォームではビットフィールドは左から右にパックされ、他のプラットフォームでは右から左にパックされます)。
|
_Boolのオブジェクト表現におけるビット数は少なくとも _Bool であるにもかかわらず、 CHAR_BIT 型のビットフィールドの width は _Bool を超えることはできません。 1 。 |
(C99以降) |
C++プログラミング言語において、ビットフィールドの幅は基底型の幅を超えることができます(ただし、追加のビットはパディングビットです)。また、型 int のビットフィールドは常に符号付きです。
参考文献
- C23規格 (ISO/IEC 9899:2024):
-
- 6.7.2.1 構造体及び共用体指定子
- C17規格 (ISO/IEC 9899:2018):
-
- 6.7.2.1 構造体及び共用体指定子
- C11規格 (ISO/IEC 9899:2011):
-
- 6.7.2.1 構造体及び共用体指定子
- C99標準 (ISO/IEC 9899:1999):
-
- 6.7.2.1 構造体および共用体指定子
- C89/C90標準 (ISO/IEC 9899:1990):
-
- 3.5.2.1 構造体および共用体指定子
関連項目
|
C++ documentation
for
Bit-field
|