2

アームベースのアーチには何が良いですか?

struct my_struct{
    struct device   *dev;
    unsigned char   a:1,
            b:1,
            v:1,
            d:1;
};

または、char を定義してビット単位の演算を使用するには:

struct my_struct{
    struct device   *dev;
    unsigned char abcd;
};
4

3 に答える 3

4

この質問では、プロセッサのアーキテクチャは重要ではないと思います。多くの点で、これは純粋にスタイルの問題です。

私の経験では、ほとんどの人は符号なし整数とビット単位の演算を使用する傾向があります。

#define MASK_B 0x20;
unsigned char field;
int b_is_set = field & MASK_B;

ビットフィールドは、主流のコードで実際に採用されるようには見えませんでした。

そうは言っても、私はあなたにとってより自然に感じる方を使用します.

于 2012-12-03T19:53:14.997 に答える
1

ビットフィールドのパッキング順序は実装定義です。つまり、宣言すると

struct my_struct {
    struct device  *dev;
    unsigned char   a:1,
                    b:1,
                    c:1,
                    d:1;
};

aまたはbまたはcまたはdが実際に存在する場所を決定するのは完全にコンパイラ次第です__BIG_ENDIAN_BITFIELD__LITTLE_ENDIAN_BITFIELD

一方、定義すると、

struct my_struct {
    struct device  *dev;
    unsigned char   abcd;
};
#define MASK_A  (1U << 0U)
#define MASK_B  (1U << 1U)
#define MASK_C  (1U << 2U)
#define MASK_D  (1U << 3U)

static inline unsigned char get(const struct my_struct *const m, const unsigned char mask)
{
    return m->abcd & mask;
}

static inline unsigned char set(struct my_struct *const m, const unsigned char mask, const unsigned char value)
{
    m->abcd = (m->abcd & mask) | (mask & value);
    return m->abcd & mask;
}

static inline unsigned char flip(struct my_struct *const m, const unsigned char mask)
{
    m->abcd ^= mask;
    return m->abcd & mask;
}

これはa、ポインターに続くバイトの最下位ビットb、2 番目のビット、c3 番目、d4 番目のビットにマップされます。

C コンパイラが をサポートしている場合static inline、これらの関数はマクロと同じくらい高速ですが、マクロに問題があるわけではありません。副作用。

これにより、ビット フィールドをグループとして操作することもできます。たとえばb、構造体に設定するには、 をt使用しますset(&t, MASK_B, MASK_B)。を設定bしてクリアaするには、 を使用しますset(&t, MASK_A | MASK_B, MASK_B)。が設定されているかどうかをテストするaには、 を使用しますget(&t, MASK_A)aまたはbが設定されているかどうかをテストするには、 を使用しますget(&t, MASK_A | MASK_B)aとの両方bが設定されているかどうかを確認するには、 を使用します(get(&t, MASK_A | MASK_B)) == (MASK_A | MASK_B))。3 つの関数はすべて、マスクが適用された結果のビット マスクを返します。つまり、他のすべてのビットはゼロです。

個人的には、この後者のアプローチを好みます。主な理由は、後者の方がより明示的であり (完全に制御できる)、汎用性が高く (個別だけでなくグループでも操作できる)、スペース効率が高い (コンパイラーはコマンドラインスイッチなどを使用しないように明示的に指示しない限り、パディングを追加します)。フラグの使用方法に応じて、マクロまたは静的インライン関数を介してフラグにアクセスすることをお勧めします。

とはいえ、構造がアプリケーションの内部にあり、大容量ストレージに保存されたり送信されたりすることがないのであれば、どちらのアプローチにも異論はありません。

于 2012-12-03T23:20:07.607 に答える
1

最初に行うことは、アライメントについて考えることです。これらの問題unaligned -memory-accessmem_alignmentについて詳しく読んでください。

スケーラビリティまたはオーバーヘッドは、2 番目に重要な要素です。この構造が何度も割り当てられる場合、たとえばエントリをキャッシュしたり、ファイル システムの内部などの構造で使用したりする場合は、物事をコンパクトに保つ​​必要があります。

可読性も非常に重要ですが、これはパフォーマンスとメンテナンスを提供する必要がある OS カーネルであるため、意識的にトレードオフを行う必要があります。

于 2012-12-03T20:37:27.143 に答える