4

要素の非常に大きな構造のステータスをすばやく監視する目的で、大きなビットフィールドを定義したいと思います。これが私がこれまでに持っているものです:

#定義 TOTAL_ELEMENTS 1021

typedef 構造体 UINT1024_tag
{
   UINT8バイト[128];
} UINT1024;

typedef 構造体 flags_tag
{
   UINT1024:TOTAL_ELEMENTS;
} flags_t;

これをコンパイルしようとすると、「エラー: ビットフィールド `<anonymous>' has invalid type」というエラー メッセージが表示されます。

ビットフィールドは特定の型でのみ使用できますか? 十分な大きさの変数を定義すれば、アプリケーションに必要な大規模なビットフィールドを定義できると考えました。ビットフィールドは、定義に使用される型より大きくてはならないからです。

ご意見やご提案をいただければ幸いです。

4

4 に答える 4

8

ビットフィールドは単一のint内に収まる必要があり、任意のサイズを使用することはできません。正直なところ、ANSIビットフィールドの実装はちょっと壊れています。実際のアプリケーションが通常必要とするパディングやレイアウトの制御など、他の多くのものも見逃しています。より大きなサイズを抽象化し、ビットフィールド構文をあきらめるために、いくつかのマクロまたはアクセサー関数を作成することを検討します。

于 2009-10-19T20:31:38.387 に答える
3

標準 C 言語では、ビットフィールドは、制限された型のセットでのみ定義できます。C89/90 では、これらの型は と に制限されていintます(あまり知られていない詳細として、このコンテキストでは が と同等であることが保証されていません)。C99 では、サポートされるセットに type が追加されました。ビットフィールドの宣言では、他の型は使用できません。signed intunsigned intintsigned int_Bool

実際には、一般的な拡張機能として、コンパイラは通常、ビットフィールド宣言で任意の整数型 (または列挙型) を許可します。しかし、structタイプ...いいえ、それを許可するコンパイラを知りません(あまり意味がないように見えることは言うまでもありません)。

于 2009-10-19T20:43:45.190 に答える
1

使用する

 UINT128 blaha;

ビットフィールドを定義していません。

ビットフィールドとは何かを理解しているかどうかわかりません。I bitfield はビット数です。構造体の配列などではありません。あなたのコードが何をすべきか正確に何を期待していますか?

編集:ああ、わかりました。いいえ、独自の型は使用できません。int のみです。

これを試してください(テストされていないコード):

struct bit1024 {
  unsigned char byte[128];
};
struct bit1024 foo;
void
set(struct bit1024*lala, int n, int v)
{
  lala->byte[n/8] |= 1<<(n % 8);
  if (!v) {
    lala->byte[n/8] ^= 1<<(n % 8);
  }
}
int
get(struct bit1024*lala, int n)
{
  return 1 & (lala->byte[n/8] >> (n % 8));
}
于 2009-10-19T20:30:22.383 に答える
0

他の人が言ったように、C標準では、ビットフィールドが添付された整数型のサイズを超えることは許可されていません。

いくつかのマクロマジックでプレーン配列を使用することをお勧めします。

#include <limits.h>
#include <stdio.h>
#include <string.h>

// SIZE should be a constant expression
// this avoids VLAs and problems resulting from being evaluated twice
#define BITFIELD(SIZE, NAME) \
    unsigned char NAME[(SIZE) / CHAR_BIT + ((SIZE) % CHAR_BIT != 0)]

static inline void setbit(unsigned char field[], size_t idx)
{ field[idx / CHAR_BIT] |= 1u << (idx % CHAR_BIT); }

static inline void unsetbit(unsigned char field[], size_t idx)
{ field[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT)); }

static inline void togglebit(unsigned char field[], size_t idx)
{ field[idx / CHAR_BIT] ^= 1u << (idx % CHAR_BIT); }

static inline _Bool isbitset(unsigned char field[], size_t idx)
{ return field[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT)); }

int main(void)
{
    BITFIELD(1025, foo);
    printf("sizeof foo = %u\n", sizeof foo);

    memset(foo, 0, sizeof foo);
    printf("%i", isbitset(foo, 1011));

    setbit(foo, 1011);
    printf("%i", isbitset(foo, 1011));

    unsetbit(foo, 1011);
    printf("%i", isbitset(foo, 1011));
}

うまくいけば、私はビット操作を台無しにしませんでした...

于 2009-10-19T21:20:00.287 に答える