sizeof(enum) ==sizeof(int) は常にですか?

これはコンパイラに依存し、列挙型によって異なる場合があります。以下はセマンティクスです

enum X { A, B };

// A has type int
assert(sizeof(A) == sizeof(int));

// some integer type. Maybe even int. This is
// implementation defined. 
assert(sizeof(enum X) == sizeof(some_integer_type));

C99 の「一部の整数型」には、拡張整数型も含まれる場合があることに注意してください (ただし、実装が提供する場合は、実装で文書化する必要があります)。列挙型は、任意の列挙子の値を格納できる型です (AB この場合)。

列挙型の使用にペナルティはないと思います。列挙子も整数定数式です (したがって、たとえば、静的変数またはファイル スコープ変数を初期化するために使用できます)。

列挙子はランタイム メモリを必要としません。列挙型の変数を作成する場合にのみ、ランタイム メモリを使用できます。列挙子をコンパイル時の定数と考えてください。

列挙子の値を格納できる型を使用し (事前に値の大まかな範囲を知っておく必要があります)、それにキャストし、ネットワーク経由で送信します。できれば、型は int32_t のような固定幅のものにする必要があります であるため、異なるマシンが関係している場合に競合が発生することはありません。または、番号を印刷して反対側でスキャンすると、これらの問題の一部が解消されます。

編集への応答

まあ、コンパイラは任意のサイズを使用する必要はありません。簡単にわかるのは、値の符号が重要であることです。符号なしの型は、一部の計算でパフォーマンスを大幅に向上させることができます。以下は、GCC 4.4.0 の動作です。 私の箱に

int main(void) {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned int"
  unsigned int *p = &a;
}

しかし、 -1 を割り当てると の場合、GCC は int の使用を選択します X の型として と互換性があります

int main(void) {
  enum X { A = -1 };
  enum X a; // X compatible with "int"
  int *p = &a;
}

オプション --short-enums の使用 これにより、すべての値に適合する最小の型が使用されます。

int main() {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned char"
  unsigned char *p = &a;
}

C99、6.7.2.2p4 は言う

脚注 108 が追加

したがって、これは実装定義であり、sizeof(enum) は sizeof(char)、つまり 1 と等しい場合があります。

整数の小さな範囲のサイズを選択する際には、常に ペナルティ。メモリを小さくすると、おそらく処理のペナルティが発生します。大きくすると、スペースが犠牲になります。これは時空間のトレードオフです。

エラー コードは拡張可能である必要があるため、通常は #define です。さまざまなライブラリが新しいエラー コードを追加する可能性があります。列挙型ではできません。


ANSI C 標準には次のように記載されています。

だから私はそれをノーと解釈します.

定義を使用すると、列挙型を使用するよりもメモリを節約できますか?列挙型は、コンパイラにより多くの情報を提供できるようにする単なる型です。実際の結果の実行可能ファイルでは、プリプロセッサが #define で作成されたマクロを変換するのと同じように、整数に変換されます。

ネットワークを介して値を転送し、相手側で処理する場合は、プロトコルを定義する必要があります。各タイプのビット単位のサイズ、エンディアン (バイトの順序) を決定し、クライアント コードとサーバー コードの両方でそれに従うようにしてください。また、たまたまうまくいったからといって、それが正しいと思い込まないでください。たとえば、選択したクライアント プラットフォームとサーバー プラットフォームのエンディアンが一致している可能性がありますが、常にそうであるとは限りません。