準拠コンパイラの場合、列挙型定数は常に型int
(と同等signed int
)です。ただし、このような定数は通常、メモリに格納されないため、そのタイプはメモリ要件にあまり影響を与えない可能性があります。
列挙型の宣言されたオブジェクトは、列挙型自体であり、char
符号付きまたは符号なし整数型と互換性があります。タイプの選択は実装によって定義されます(つまり、コンパイラーは選択できますが、選択方法を文書化する必要があります)。唯一の要件は、型がすべての定数の値を格納できる必要があることです。
int
定数が列挙型ではなく型であるのは確かに奇妙ですが、それが言語の定義方法です(理由は歴史的であり、C ++には異なる規則があります)。
たとえば、次のようになります。
enum foo { x, y, z };
enum foo obj;
obj = z;
式z
は型int
であり、値は2(10進定数と同じ2
)ですが、オブジェクトobj
は型enum foo
であり、コンパイラーによっては1バイト程度の場合もあります。割り当てには、からへobj = z;
の暗黙の変換が含まれます(その変換には追加のコードが必要な場合と不要な場合があります)。int
enum foo
一部のコンパイラは、列挙型に選択する型を指定するための非標準的な方法を提供する場合があります。いくつかの方法で標準に違反することさえあります。コンパイラのドキュメントを参照し、の値を出力し、sizeof (enum foo)
必要に応じて、生成されたコードを調べます。
コンパイラは、言語によって課せられた制約の範囲内で合理的な決定を下す可能性があります。メモリ不足の組み込みシステムを対象としたコンパイラの場合、コンパイラが小さいタイプを選択するか、小さいタイプを指定できるようになる可能性が特に高くなります。コンパイラのドキュメントを参照してください。
Ianの回答が示唆しているように、メモリ使用量を自分で制御したい場合は、char
またはunsigned char
オブジェクトを使用できます。enum
ただし、定義を使用して定数を定義することはできます。例えば:
enum { x, y, z }; // No tag, so you can't declare objects of this type
typedef unsigned char foo; // an enum_foo object is guaranteed to be 1 byte
foo obj = z;
参照: C標準のセクション6.7.2.2 。リンクは、2011ISOC標準の最近のドラフトの1.7メガバイトのPDFへのリンクです。この特定のセクションは、1989年以降大幅に変更されていません。