Cの列挙型のサイズは?


140

列挙値のセットを作成していますが、各列挙値は64ビット幅である必要があります。私が正しく思い出せば、列挙型は一般的にintと同じサイズです。(少なくともGCCでは)コンパイラが値を保持するために必要な任意の幅を列挙型にできることをどこかで読んだと思いました。それで、64ビット幅の列挙型を持つことは可能ですか?


1
だから私がよく理解すれば、2 ^ 32列挙では十分ではありませんか?それとも整合の懸念ですか、なぜ32ではなく64にする必要があるのでしょうか。
jokoon

1
@jokoon:正直言ってもう思い出せない。列挙型に2 ^ 32-1より大きい値を含める必要があったと思います。
mipadi 2013年

1つの使用法は、列挙型とポインタの間の和集合が必要な場合です。
デミ

回答:


97

enum唯一のホールドに十分な大きさであることが保証されintた値。コンパイラーは、定義された列挙定数に基づいて使用される実際のタイプを自由に選択できるため、ユーザーが定義した値を表すことができる場合は、より小さいタイプを選択できます。収まらない列挙定数が必要な場合は、intコンパイラ固有の拡張機能を使用してこれを行う必要があります。


12
最初の文は最後の文と矛盾しているようです。の制約はenumより大きいintか、小さいか @MichaelStumの回答に従うと、最初の文は「An enumint値に収まることが保証されているだけ」になります。
HaskellElephant 2014年

2の補数プラットフォームでの実装に依存した醜いハックとして(最近のすべてのシステムですか?)、負の値が含まれていることを確認して、列挙型をintと同じ大きさにすることができます。ただし、推奨される手法ではありません。
永続化2016

7
この答えは、列挙型がと同じくらい大きいことを示唆しているようintです。C99を参照するMichael Stumの回答は、enumはと同じくらい小さいかもしれないと述べていcharます。
フランク・カスターズ2017

3
この回答の最初の文は正しくありません。enumのみ列挙型で最大の列挙子の値を保持するのに十分な大きさであることが保証されます。
MM

91

現在のC標準(C99)から取得:http : //www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2列挙指定子
[...]
制約
列挙定数の値を定義する式は、intとして表現可能な値を持つ整数定数式でなければなりません。
[...]
各列挙型は、char、符号付き整数型、または符号なし整数型と互換性があります。タイプの選択は実装定義ですが、列挙型のすべてのメンバーの値を表すことができます。

コンパイラーは標準に従うのが得意ではありませんが、基本的には次のとおりです。列挙型がint以外のものを保持している場合、「サポートされていない動作が1〜2年後に発生する可能性があります」という深い領域にいます。


3
それだけがあれば、以下は有効だと思います:enum {LAST = INT_MAX、LAST1、LAST2}; したがって、LAST2はintで表現できませんが、それを定義する式はありませんでした。
Johannes Schaub-litb 2008

4
実際のPDFでは、次のように定義されています。「列挙子リストの識別子は、int [...]型の定数として宣言されています」。冗長にならないように省略しました。
Michael Stum

2
注「符号付き整数型、または符号なし整数型」。必ずしも必要はない。およびも整数型であり、実装が選択するものは何でも、すべての値が適合する必要があります(「列挙型のすべてのメンバーの値を表すことができるものとします」)。intshortlong

3
注意:列挙定数列挙型 は同じものではありません。前者は列挙型宣言リストの内容であり、後者は実際の変数です。したがって、列挙定数はでなければなりませんがint、実際の列挙変数は別の型である可能性があります。これは、標準でよく知られている不整合です。
ランディン2017

1
以下の場合:ランディンのポイントを明確にするためにenum my_enum { my_value }my_value種類を持っていますintが、enum my_enum少なくとも、すべての列挙値を表す必要があり、実装定義された型を持つことができます。したがってmy_value、への変換が狭まる可能性がありますが、enum my_enumオーバーフローしないことが保証されています。
P O'Conbhui

17

以前の答えは正しいですが、一部のコンパイラには標準を破ってすべての値を含む最小の型を使用するオプションがあります。

GCCの例(GCCマニュアルのドキュメント):

enum ord {
    FIRST = 1,
    SECOND,
    THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )

11
実際、私が見る限り、これは標準を破ることはありません。Michael Stumの回答で説明されているように、標準では、すべての値が適合する限り、コンパイラーはenumの実際のタイプを選択できます。
sleske 2015

2
私は、列挙型の限られた範囲の値を利用してより小さい型に格納するMacOS C ++コンパイラーを使用してきました。それがMetrowerks CodewarriorかXCodeかを思い出せません。これはC ++標準の範囲内です。一般に、sizeof(MyEnum)== sizeof(int)と想定することはできません。
永続化2016

0

enumの最後の値を、enumにしたいサイズにするのに十分な大きさの値に設定するだけで、そのサイズになります。

enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};

1
このコードは質問に答えることがありますが、問題を解決する方法や理由に関する追加のコンテキストを提供することで、回答の長期的な価値が向上します。
レオパル

-1

enum変数のサイズは制御できません。それは完全な実装に依存し、コンパイラが使用する整数の名前を格納するオプションを提供しますenumので、enum整数のサイズは以下の通りです。


-1

C言語でenumは、はのサイズであることが保証されていますint-fshort-enums短くするためのコンパイル時オプション()があります(これは主に値が64K以下の場合に役立ちます)。サイズを64ビットに増やすコンパイル時オプションはありません。


-6

このコードを考えてみましょう:

enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;

それは出力として4を与えます。したがって、要素の数に関係なくenum、そのサイズは常に固定されます。


6
Michael Stumの答えは正しいです。これはコンパイラ固有です。IAR EWARMを使って自分で試してみることができます。IAR EWARMは、例として1を示しています。255の項目にそこにある場合、それは2に上がる256番目の項目を追加した後、それはまだ1が示し
desowin

10
問題はC ++に関するものではありません。
Michas

3
CまたはC ++を作成する前に理解しておくべき重要なこと:コンパイルできるからといって、規格に準拠しているとは限りません。与えられた結果が得られるからといって、コードを実行するときに常にそうする、または他のユーザーがそうすることをスタンダードが言っているわけではありません。このような質問には、標準または少なくとも特定のコンパイラ/ ABIの実装定義仕様を参照する回答が必要です。プログラムをコンパイルして実行し、ある日に1つの結果を確認するだけでは、そのような質問については何の教訓もありません(他のことについてはほとんどありません)。
underscore_d
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.