2010-11-28 14 views
4

ビットパック構造の内部に配列を配置したいと考えています。私は静的に配列のサイズを知っています(32)、配列の各要素を1つのビットにしたいと思います。私はカップルの事を試してみたが、gccはびくともしませんビットパック構造の内部の配列

struct example_s { 
    // ... 
    unsigned int flags[32] : 32; 
} __attribute__((__packed__)); 

:たとえば、私が何かのように言うことができるようにしたいと思います。パックド配列内の要素を反復処理するクリーンなコードを書くことができるように、これを行うことができれば幸いです。アイデア?

+0

これはメモリマップI/O用ですか? – nmichaels

+0

ビットパック構造体とは何ですか? –

+0

これは、スタックに格納され、スタックからアクセスされる実行時メタデータの一部です。 – mhahnenb

答えて

6

あなたは、単に(32ビット)int型に入れている場合、あなたはきれいにこのようなループのためにビットを反復処理することができます。配列のインデックスの構文よりも書くことが

for (bit = 0; bit < 32; bit++) 
    flagValue = ((flags & (1<<bit)) != 0; 

はるかに困難はありません。

コードを読みやすくするためにビットツイイドを非表示にするには、関数やマクロを使用してビットにアクセスすることもできます。 GetFlag(bit)

+0

ええ、マクロは行く方法のように見えています。しかたがない! – mhahnenb

1

ビットフィールドのメンバ要素にはアドレスがないので、それらの配列を宣言できたとしても、それを使用する方法はありません(Cの配列アクセスはすべてポインタの算術演算と逆参照です)。しかし、より大きな型のビットを使用して独自のビット配列をコーディングするのは簡単です。ジェイソンは基本について説明しました。本当に良い理由がなければ、ビットフィールドの使用を避けるべきです。彼らは通常、彼らが価値があるよりも多くのトラブルです。

+0

structメンバーについても同じことを言うことができます。コンパイラは通常、構造体のベースアドレスからオフセットを生成します。ビットパック構造体の値を取得して設定するには、もう少し追加の魔法が必要です。したがって、配列のために同じ種類の背後にある魔法を実行できない理由はありません。そして、私はビットフィールドを使う良い理由があります:-) – mhahnenb

+0

いいえ 'struct foo'がメンバ' char bar [10] 'を持っているなら' foo.bar'は 'char *'と評価される式です。 'foo.bar [2]'は '*(foo.bar + 2)'として評価され、すべて機能します。配列構文 'a [b]'は、 '*(a + b)'の構文的な砂糖(およびカッコなしの便利なグループ)です。 –

+0

ビットフィールドを使用する "正当な理由"がある場合、私はあなたがJasonの答えを理解できなかったと思います。ビット配列の実装を調べてみてください。これはgoogleかSOの過去の質問のいずれかです。あなたは満足できる答えを見つけるでしょう。 –