Sizeof(enum)== sizeof(int)、常にですか?
通常の慣行は何ですか?これらの戻り値の型をネットワーク経由で転送する必要があり、もう一方の端で何らかの処理を行う必要がある場合、enums /#defines/const intをどのように使用しますか。
編集-コンパイラはマクロをシンボリックにリンクしないので、ネット上で確認するだけで、人々はその後どのようにデバッグし、整数値をヘッダーファイルと比較しますか?
From Answers —明確にする必要があるため、この行を下に追加しています—
「つまり、実装定義であり、sizeof(enum)可能性があります sizeof(char)、つまり1です。」
コンパイラに依存し、列挙型によって異なる場合があります。以下はセマンティクスです
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の「整数型」には拡張整数型も含まれる場合があることに注意してください(ただし、実装は、提供する場合は文書化する必要があります)。列挙のタイプは、任意の列挙子の値を格納できるタイプです(この場合はA
およびB
)。
列挙型の使用にはペナルティはないと思います。列挙子も整数定数式であるため(たとえば、静的変数またはファイルスコープ変数を初期化するために使用できます)、可能な場合はマクロよりも優先します。
列挙子にはランタイムメモリは必要ありません。列挙型の変数を作成する場合にのみ、ランタイムメモリを使用できます。列挙子をコンパイル時定数と考えてください。
列挙子の値を格納できる型を使用し(事前に大まかな値の範囲を知っている必要があります)、それにキャストし、ネットワーク経由で送信します。タイプは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;
}
GCCのオプション--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によると
各列挙型は、char、符号付き整数型、または符号なし整数型と互換性があります。タイプの選択は実装定義です108)が、列挙のすべてのメンバーの値を表現できなければなりません。 [...]
脚注108が追加
実装では、すべての列挙定数が見つかるまで、どの整数型の選択を遅らせることができます。
したがって、実装定義であり、sizeof(enum)はsizeof(char)と等しい場合があります。つまり、1です。
いくつかの小さな範囲の整数のサイズを選択する場合、常にのペナルティがあります。メモリを小さくすると、おそらく処理のペナルティがあります。大きくすると、スペースにペナルティが生じます。これは時間と空間のトレードオフです。
エラーコードは、拡張可能である必要があるため、通常は#definesです。異なるライブラリが新しいエラーコードを追加する場合があります。列挙型ではできません。
Sizeof(enum)== sizeof(int)、常に
ANSI C規格は次のように述べています。
各列挙型は、char、符号付き整数型、または符号なし整数型と互換性があります。タイプの選択は実装定義です。 (6.7.2.2列挙指定子)
だから、それはノーという意味だと思います。
これが当てはまる場合、メモリを節約するため#DEFINEの方が優れています。
Enumを使用するよりも、defineを使用するとメモリを節約する方法は何ですか?列挙型は、コンパイラにより多くの情報を提供できる単なる型です。実際の結果の実行可能ファイルでは、プリプロセッサが#define inで作成されたマクロをその値に変換するように、整数に変換されます。
通常の練習は何ですか。ネットワーク上でこれらの戻り値の型を転送する必要があり、もう一方の端でいくつかの処理を行う必要がある場合
ネットワークを介して値を転送し、もう一方の端で値を処理する場合は、プロトコルを定義する必要があります。各タイプのビット単位のサイズ、エンディアンネス(バイトの順序)を決定し、クライアントコードとサーバーコードの両方でそれを確実に順守してください。また、たまたま動作するからといって、それが正しいと思っているだけではありません。たとえば、選択したクライアントプラットフォームとサーバープラットフォームのエンディアンが一致する場合もありますが、必ずしもそうとは限りません。
いや.
次のような列挙型を定義する場合:
enum MyEnum1 {
A=1,
B=2,
C=3
};
// will have the sizeof 1 (fits in a char)
enum MyEnum1 {
A=1,
B=2,
C=3,
D=400
};
// will have the sizeof 2 (doesn't fit in a char)
詳細 メーリングリストから
一部のコンパイラでは、列挙のサイズは、列挙に含まれるエントリの数に依存します。 (255エントリ未満=>バイト、255エントリ以上int)しかし、これはコンパイラとコンパイラ設定に依存します。