3

コロンを使用して指定されたサイズのビットフィールドを宣言したい (構文が何と呼ばれるか思い出せない)。私はこれを書きたい:

void myFunction() 
{   
  unsigned int thing : 12;
  ...
}

しかし、GCC は構文エラーだと言っています (ネストされた関数を記述しようとしていると思われます)。私はこれをしても問題ありません:

struct thingStruct
{
  unsigned int thing : 4;
};

そして、そのような構造体を 1 つスタックに置く

void myFunction() 
{   
  struct thingStruct thing;
  ...
}

これは、セマンティックの問題ではなく、構文によって妨げられていると私に信じさせます。

では、なぜ最初の例がうまくいかないのでしょうか? 私は何が欠けていますか?

4

4 に答える 4

7

構造体内でのみビットフィールドを宣言できるため、最初の例は機能しません。あなたが言ったように、これは構文であり、意味論ではありませんが、あります。ビットフィールドが必要な場合は、構造体を使用してください。

于 2010-08-12T19:41:33.287 に答える
4

なぜそんなことをしたいのですか?12 のビット フィールドは、すべての一般的なアーキテクチャで、少なくとも 16 ビットまたは 32 ビットにパディングされます。

整数変数の幅を確保したい場合はinttypes.hint16_tや などの型を使用しますint32_t

于 2010-08-12T19:49:55.333 に答える
2

struct他の人が言ったように、ビットフィールドは a (またはunion、しかしそれはあまり役に立ちません)内で宣言する必要があります。なんで?ここに2つの理由があります。

  • 主に、コンパイラ作成者の作業を容易にするためです。ビットフィールドは、バイトからビットを抽出するために、より多くのマシン命令を必要とする傾向があります。.ビットフィールドにできるのはフィールドだけで、変数やその他のオブジェクトはできないため、コンパイラの作成者は、または->演算子が含まれていない場合、それらについて心配する必要はありません。

  • しかし、言語設計者は、プログラマーの生活を楽にするために、コンパイラー作成者の仕事を難しくすることがあります。まあ、s 以外のビットフィールドに対するプログラマからの需要はあまりありませんstruct。その理由は、プログラマーが単一のデータ構造内にいくつかの小さな整数を詰め込もうとしているときに、ほとんどビットフィールドを気にするだけだからです。それ以外の場合は、単純な整数型を使用します。

他の言語には整数の範囲型があります。たとえば、変数の範囲を 17 から 42 に指定できます。C ではオーバーフローの実装チェックを必要としないため、C ではあまり呼び出されません。したがって、C プログラマーは、目的の範囲を表すことができる型を選択するだけです。とにかく境界をチェックするのは彼らの仕事です。

C89 (つまり、ほぼどこにでもある C 言語のバージョン) は、少なくとも n ビットを持つ型の限られた選択肢を提供します。unsigned char8 ビット用unsigned short、16 ビットunsigned long用、および 32 ビット用 (および符号付きバリアント) があります。uint_least8_tC99 では、 、uint_least16_tuint_least32_tおよび と呼ばれる型の幅広い選択肢が提供されますuint_least64_t。これらの型は、少なくともその数の値ビットを持つ最小の型であることが保証されています。実装は、 などの他のビット数の型を提供できますuint_least12_tが、ほとんどは提供しません。これらの型は で定義され<stdint.h>ており、標準では要求されていませんが、多くの C89 実装で使用できます。

于 2010-08-12T20:37:38.250 に答える
1

ビットフィールドは、実装に依存する特定の機能にアクセスするための一貫した構文を提供します。その機能の最も一般的な目的は、特定のデータ項目を特定の方法でビットに配置することです。2 つの項目 (ビット フィールドであるかどうかに関係なく) が構造体で連続する項目として宣言されている場合、それらは連続して格納されることが保証されます。ストレージ クラスやスコープに関係なく、個々の変数にはそのような保証はありません。構造体に次が含まれている場合:

構造体 foo {
  未署名のバー: 1;
  署名されていない boz: 1;
};

bar と boz が連続して保存されることが保証されています(実際には保証されていないと思いますが、同じ保存場所にある可能性が最も高いです)。対照的に、'bar' と 'boz' は単一ビットの自動変数であり、それらがどこに格納されるか分からないため、それらをビットフィールドとして使用するメリットはほとんどありません。それらが他の変数とスペースを共有した場合、同じバイト内の異なるビットを読み書きする異なる関数が互いに干渉しないことを確認するのは困難です。

一部の組み込みシステム コンパイラは、8 から 1 バイトにパックされた本物の「ビット」型を公開していることに注意してください。このようなコンパイラには一般に、ビット変数のみを格納するために割り当てられるメモリ領域があり、コードを生成するプロセッサには、個々のビットをテスト、設定、およびクリアするためのアトミック命令があります。ビットを保持するメモリ位置は、そのような命令を使用してのみアクセスされるため、競合の危険はありません。

于 2011-12-16T18:12:11.820 に答える