0

ヘッダー ファイル内の言語のデータ型によって宣言された構造体の変数。通常、データ型は変数の宣言に使用されますが、他のデータ型はプリプロセッサに渡されます。変数を宣言するためにプリプロセッサに送信するデータ型をいつ使用する必要がありますか? データ型と変数がプロセッサに送信されるのはなぜですか?

#define DECLARE_REFERENCE(type, name) \
union { type name; int64_t name##_; }

typedef struct _STRING
 {
   int32_t flags;
   int32_t length;

   DECLARE_REFERENCE(char*, identifier);
   DECLARE_REFERENCE(uint8_t*, string);
   DECLARE_REFERENCE(uint8_t*, mask);
   DECLARE_REFERENCE(MATCH*, matches_list_head);
   DECLARE_REFERENCE(MATCH*, matches_list_tail);

   REGEXP re;

 } STRING;
4

2 に答える 2

1

このコードが宣言に対してこれを行っているのはなぜですか? の本体がDECLARE_REFERENCE示すように、型と名前がこのマクロに渡されると、宣言だけでなく、他の未知の目的のために、名前から何か他のものも構築されるためです。変数を宣言したいだけなら、これはしません。単純に 1 つの変数を宣言するのとは別のことをします。

それは実際に何をしますか?マクロが宣言する共用体は、同じスペースに別の型としてアクセスするための 2 番目の名前を提供します。この場合、参照自体を取得することも、ビット パターンの変換されていない整数表現を取得することもできます。int64_tとにかく、それがターゲット上のポインターと同じサイズであると仮定します。

これにマクロを使用すると、すぐに思いつくいくつかの目的に役立つ可能性があります。

  1. キーストロークを節約
  2. コードを読みやすくします - ただし、マクロの意味をすでに知っている人のみ
  3. 参照データを取得する 2 番目の方法がデバッグ目的でのみ使用される場合、リリース ビルドでは簡単に無効にすることができ、残っているデバッグ コードでコンパイラ エラーが生成されます。
  4. アクセス パスのセカンダリステータスを強制し、構造体とその正式なインターフェイスに何が含まれているかだけを見たい人から隠します。

これを行う必要がありますか?いいえ。これは単に変数を宣言するだけでなく、他のこと行います。他のことは、含まれているプログラムの残りの部分の内部に明らかに固有のものです。プログラムの残りの部分を見なければ、プログラムが何をするかを完全に理解することはできません。

プログラムの内部に特有のことをする必要がある場合、(願わくば) いつ、このような独自のものを発明するべきかを知ることができます (ほとんどの場合、決してそうではありません)。ただし、他の人をコピーしないでください。

したがって、ここでの全体的な教訓は、人々が単純な C で書いているのではなく、特定のアプリケーションに合わせてコーディングしている場所を特定し、それら 2 つを分離し、言語全体のガイドラインとして特定のプログラムの癖を取り入れないようにすることです。

于 2013-10-18T15:27:23.087 に答える
0

相互に何らかの関係があることが保証されている多数の宣言が必要な場合があります。連続して番号を付ける必要がある定数などの単純な種類の関係は、enum宣言を使用して処理できますが、一部のアプリケーションでは、コンパイラが直接処理できないより複雑な関係が必要です。たとえば、列挙値のセットと文字列リテラルのセットを持ち、それらが互いに同期していることを確認したい場合があります。次のようなものを宣言した場合:

#define GENERATE_STATE_ENUM_LIST \
  ENUM_LIST_ITEM(STATE_DEFAULT, "Default") \
  ENUM_LIST_ITEM(STATE_INIT, "Initializing") \
  ENUM_LIST_ITEM(STATE_READY, "Ready") \
  ENUM_LIST_ITEM(STATE_SLEEPING, "Sleeping") \
  ENUM_LIST_ITEM(STATE_REQ_SYNC, "Starting synchronization") \
  // This line should be left blank except for this comment

次に、コードはGENERATE_STATE_ENUM_LISTマクロを使用して型と文字列配列を宣言し、enum項目がリストに追加または削除された場合でも、各文字列が適切な列挙値と一致するようにします。対照的に、配列と列挙型の宣言が別々の場合、一方に新しい状態を追加し、他方に追加しないと、値が「非同期」になる可能性があります。

特定のケースでのマクロの目的はわかりませんが、パターンは合理的なものになる場合があります。最大の「問題」は、C プリプロセッサを (ab) 使用して、そのような関係を有効だが醜い C コードで表現できるようにする方がよいか、それとも他のツールを使用してリストを取得する方がよいかということです。状態から適切な C コードを生成します。

于 2013-10-18T19:18:43.733 に答える