ここから本文です

C言語で、構造体の中のビットフィールドの共用体は実現できますか?

cbi********さん

2010/7/1012:24:36

C言語で、構造体の中のビットフィールドの共用体は実現できますか?

現在C言語でデバイスドライバを作成しています。
あるレジスタ(unsigned char型,8bit)の下位6bitについて、6bit同時に値を設定する場合と1bitずつ値を設定する場合の両方を1つの構造体で実現したいと考えています。そこで、次のような構造体の型を考えました。

コンパイラはgcc4系です。
typedef unsigned char UCHAR;
typedef struct {
union {
UCHAR val_all : 6;
struct {
UCHAR val_0 : 1;
UCHAR val_1 : 1;
UCHAR val_2 : 1;
UCHAR val_3 : 1;
UCHAR val_4 : 1;
UCHAR val_5 : 1;
} __attribute__((packed)) val_each;
};
UCHAR rsvd : 2;
} __attribute__((packed)) mytype;

以下のような使用方法を想定しています。
mytype *aaa = レジスタアドレス;
aaa->val_all = 0x10;
aaa->val_each.val_4 = 1;

ということが実現できればよいのですが、現状ではsizeof(mytype)をすると2が返ってきます。

おそらく、unionの中のstructが6bitで作れていない(パディングなしでもstructサイズはバイト単位?)のが原因と思っています。

上記構造体を1バイトで確保する方法、あるいは、別の方法でも構いませんのでビットアクセスと多ビットアクセスを同時に提供できる方法があれば、ご教授お願いします。

閲覧数:
2,944
回答数:
2
お礼:
250枚

違反報告

ベストアンサーに選ばれた回答

pro********さん

2010/7/1013:23:04

unionもsturctも、サイズはバイト単位です。不足部分には、詰め物が入ります。
unionの外のstructの存在意義が分かりませんが、

typedef union {
struct {
unsigned char val : 6;
unsigned char rsvd : 2;
} all;
struct {
unsigned char val_0 : 1;
unsigned char val_1 : 1;
unsigned char val_2 : 1;
unsigned char val_3 : 1;
unsigned char val_4 : 1;
unsigned char val_5 : 1;
unsigned char rsvd : 2;
}each;
unsigned char byte;//無くてもいい
} mytype;

というようなコードになります。
ただし、

aaa->val_all = 0x10;

という使い方ではなく

aaa->all.val = 0x10;

という風になります。

短く書きたいなら

aaa->byte = 0x10;

でもいいのですが、ビットフィールドの割付方法は処理系依存なので、与える値は適宜修正する必要があるでしょう。

質問した人からのコメント

2010/7/10 22:56:36

成功 なるほど! 提供する型(mytype)をunionにするとは思いつきませんでした。
structを使わないといけないと、自分の中で決めてかかっていました。。。まさに目からウロコでした!!

期待通りの回答、ありがとうございました。

ベストアンサー以外の回答

1〜1件/1件中

wis********さん

編集あり2010/7/1013:21:26

UCHAR rsvd : 2;
を削除すればいいと思います。

struct {

} __attribute__((packed)) val_each;
でビットフィールドの連続割り当ては完了し、この構造体は1バイトの大きさを持ちます。6ビットではありません。

さらに、ビットフィールドの記述を続行しているので、UCHAR rsvd : 2;は別の1バイトに割り付けられます。

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる