スポンサーリンク
ビットフィールドを構造体で表現
構造体でビットフィールドを管理できます。
例えば、下記は、1ビット単位で4つのフィールドを定義しました。
typedef struct{ unsigned int B0 : 1; unsigned int B1 : 1; unsigned int B2 : 1; unsigned int B3 : 1; } Reg_t;
共用体で、下記のように定義することで、ビットフィールドで定義した値を、unsigned intの単位で参照できます。
typedef union{ Reg_t regBit; unsigned int reg; }RegUnion_t;
例えば、下記のようにビットフィールド単位で値を代入して、
regUnion.reg = 0; regUnion.regBit.B3 = 1; regUnion.regBit.B2 = 1; regUnion.regBit.B1 = 0; regUnion.regBit.B0 = 1;
unsigned intの単位で参照します。これが共用体の効果ですね。
printf("reg=%d\n", regUnion.reg);
スポンサーリンク
サンプルコード
下記がサンプルコードになります。
$ cat sample.c #include <stdio.h> typedef struct{ unsigned int B0 : 1; unsigned int B1 : 1; unsigned int B2 : 1; unsigned int B3 : 1; } Reg_t; typedef union{ Reg_t regBit; unsigned int reg; }RegUnion_t; int main(){ RegUnion_t regUnion; regUnion.reg = 0; regUnion.regBit.B3 = 1; regUnion.regBit.B2 = 1; //regUnion.regBit.B1 = 3; regUnion.regBit.B1 = 0; regUnion.regBit.B0 = 1; printf("size=%lu\n", sizeof(regUnion.regBit)); printf("B3=%d \nB2=%d \nB1=%d \nB0=%d\n", regUnion.regBit.B3, regUnion.regBit.B2, regUnion.regBit.B1, regUnion.regBit.B0); printf("reg=%d\n", regUnion.reg); return 0; }
下記が実行結果になります。
$ gcc -o sample sample.c $ ./sample size=4 B3=1 B2=1 B1=0 B0=1 reg=13
スポンサーリンク
warning: implicit truncation from 'int' to bit-field changes value from 2 to 0
定義したビットフィールドのビット幅を超えて、値を代入すると、
warningがでます。
例えば、ビット幅を1で定義しているところに、
typedef struct{ 〜省略〜 unsigned int B3 : 1; } Reg_t;
ビット幅1を超えて、値を代入すると、
regUnion.regBit.B1 = 3;
下記のような、warningがでます。
$ gcc -o sample sample.c sample.c:21:21: warning: implicit truncation from 'int' to bit-field changes value from 3 to 1 [-Wbitfield-constant-conversion] regUnion.regBit.B1 = 3; ^ ~ 1 warning generated.
メモリサイズとアライメント
ビットフィールドで定義された構造体のメモリサイズは、アライメントされてメモリサイズとなります。
例えば、下記の場合は4バイトのint型なので、下記のように31ビットで定義しても、メモリサイズは4バイトになります。
typedef struct{ unsigned int B0 : 1; unsigned int B1 : 2; unsigned int B2 : 3; unsigned int B3 : 25; } Reg_t;
下記のように、33ビットとすると、4バイトアライメントなので、メモリサイズは8バイトになりますね。
typedef struct{ unsigned int B0 : 1; unsigned int B1 : 2; unsigned int B2 : 3; unsigned int B3 : 27; } Reg_t;
スポンサーリンク