すでにこの関連する質問を読んでいますが、もう少し具体的なものを探していました。
- 列挙型の幅をコンパイラに具体的に伝える方法はありますか?
- もしそうなら、どのようにしますか?C# で指定する方法を知っています。Cでも同様に行われますか?
- やる価値はありますか?列挙型の値が関数に渡されるとき、サイズに
int
関わらず値として渡されますか?
すでにこの関連する質問を読んでいますが、もう少し具体的なものを探していました。
int
関わらず値として渡されますか?GCCを使用している場合、フラグがあると思います。
-fshort-列挙型
列挙型の幅をコンパイラに具体的に伝える方法はありますか?
一般的にはNo. 標準 C にはありません。
やる価値はありますか?
それは文脈に依存します。関数にパラメーターを渡すことについて話している場合は、いいえ、行う価値はありません (以下を参照)。列挙型から集計を構築するときにメモリを節約することが目的である場合は、実行する価値があるかもしれません。ただし、C では、集計で列挙型の代わりに適切なサイズの整数型を使用できます。C (C++ とは対照的に) では、列挙型と整数型はほとんどの場合交換可能です。
列挙値が関数に渡されるとき、int サイズの値として渡されますか?
最近の多くの (ほとんどの) コンパイラは、すべてのパラメータを特定のハードウェア プラットフォームの自然なワード サイズの値として渡します。たとえば、64 ビット プラットフォームでは、多くのコンパイラは、int
そのプラットフォームで型に 32 ビットが含まれていても、実際のサイズに関係なく、すべてのパラメーターを 64 ビット値として渡します (したがって、通常は "int-サイズ」の値)。このため、パラメーターを渡す目的で列挙型のサイズを最適化しようとしても意味がありません。
適切な値を定義することで、少なくとも特定のサイズにすることができます。たとえば、列挙型を と同じサイズで保存したい場合int
、すべての値が に収まる場合でも、次のchar
ようにすることができます。
typedef enum {
firstValue = 1,
secondValue = 2,
Internal_ForceMyEnumIntSize = MAX_INT
} MyEnum;
ただし、動作は実装に依存する可能性があることに注意してください。
お気づきのように、そのような値を関数に渡すと、とにかく int に展開されますが、配列または構造体で型を使用している場合、サイズが重要になります。要素のサイズを本当に気にするのであればint8_t
、int32_t
、 などの型を実際に使用する必要があります。
列挙型が構造体の一部である場合は、別の方法もあります。
struct something {
:0;
enum whatever field:CHAR_BIT;
:0;
};
:0; 列挙型フィールドが通常のフィールドに囲まれている場合は省略できます。前に別のビットフィールドがある場合、:0 は、それに続くフィールドの次のバイトへのバイトアライメントを強制します。
列挙型に割り当てられた値によって異なります。
例: 2^32-1 より大きい値が格納されている場合、enum 全体に割り当てられるサイズは次のサイズに変更されます。
0xFFFFFFFFFFFF 値を enum 変数に格納します。32 ビット環境でコンパイルしようとすると警告が表示されます (四捨五入警告)。64 ビット コンパイルの場合と同様に、コンパイルは成功し、割り当てられるサイズは 8 バイトになります。
別の方法は、次のように列挙型をユニオン内でキャストすることです。
union char_size {
char a;
enum {
a = 1,
b = 2,
} val;
};
そうすることで、コンパイラは enum を char 内に収めるよう強制されます。