2009-04-27 14 views
20

C enum宣言で最後にカンマが必要ですか?C enumの最後のカンマは必須ですか?

つまりVAL3が必要な場合はカンマですか?

enum{Val1, Val2, Val3,} someEnum; 

いいえ、それは必須ではありませんし、コード明確にするために省略されなければならない/アウトで

おかげ

+9

標準C89では、この最後のカンマは明示的に禁止されていました。 C99では、彼らはそれを可能にします。それを残すことの副作用は、厳密なC89コンパイラではコンパイルできないということです。 –

答えて

36

必須ではありません。 enum-specifierの最初の2つの形式、末尾にカンマを持つ1つずつのない

enum-specifier: 
    enum identifieropt { enumerator-list } 
    enum identifieropt { enumerator-list , } 
    enum identifier 
enumerator-list: 
    enumerator 
    enumerator-list , enumerator 
enumerator: 
    enumeration-constant 
    enumeration-constant = constant-expression 

お知らせ:C99のセクション6.7.2.2は、などの構文を示しています。

あなたが(例えば) Val4Val5に追加したい場合は、あなただけなし Val3行をコピーして貼り付け、
enum { 
    Val1, 
    Val2, 
    Val3, 
} someEnum; 

:私はそれを使用して見てきました

一つの利点は、のようなものですコンマを調整することを心配する必要があります。

また、コメントで指摘されているように、最終的な値に対して特別な処理を必要としないように自動化されたコードジェネレータを単純化することもできます。彼らはすべての値の後にカンマをつけて出力することができます。

これはしばしば、見SQLに例えることができます。その場合は

select fld1, fld2 from tbl where 1=1 and fld1 > 8 

あなたが最初の句とand前に前にwhereを配置する必要がないように、where 1=1しかありそれぞれ後続のもの。 whereが既に存在し、追加したものすべてにandを使用するという事実だけに頼ることができます。

まともなDBMSのクエリオプティマイザは、に行く前に、そのような一定の句を取り除くことができるはずです一部の人々は、これは怠惰のにおいと、彼らは右だと思うかもしれないが、それは

:-)必ずしも悪いことではありませんデータベーステーブル

+8

私が聞いたもう一つの理論的根拠は、マシン生成コードの場合です。 –

1

それを残してのいずれかの副作用があります。その有無は効果がありません。

+2

末尾のカンマに意味値がないと言うのはかなり正確です。これがないと、コード管理の利便性が低下する可能性があります。末尾にカンマがないと、コードはどのように明確になりますか? –

+0

enumの最後の要素の直後にブレースが付いていると、すぐにわかります。私は主観的だと思います。 – sharptooth

3

いいえ、それは必須ではありません - 実際には私は悪いスタイルがあると言います。

4

いいえ必須ではありません。その理由は、コンマが存在するかどうかを心配する必要がなければ、切り取りと貼り付けのコードを簡単にするためです。

3

すでに述べたように、必須ではありません。末尾のカンマがサポートされている理由は、項目が1行に1つずつ配置されていると仮定すると、切り取り/貼り付けまたはドラッグ/ドロップを使用して項目の順序を便利に並べ替えることができ、構文エラーを生成せずに最後の項目をコメントアウトする。末尾のカンマを省略すると正当ですが、これらのコード管理の利点が失われます。

私は忘れてしまいましたが、ニックはかなり正しいです。私もコンパイラ指令で末尾のカンマを利用しました。それがなければ、条件付きコードはもっと厄介で読みにくいでしょう。

2

マクロを使用していると言うと、オプションで便利です(例:

#ifdef _FLAG 
    #define OPTS opt_four, opt_five, 
#else 
    #define OPTS // none 
#endif 
enum { 
    opt_one, 
    opt_two, 
    opt_three, 
    OPTS 
}; 
0

必要ありません。そのあなたが1を追加した場合、Infactはいくつかのコンパイラは文句を言います。 Visual Studio 6など。
カンマの1つの用途は、cマクロを使用して列挙型を作成することです。

#define ELEMENT(x) x, 

enum MyElements { 
    ELEMENT(a) 
    ELEMENT(b) 
    ELEMENT(c) 
}; 

このパターンは、要素で行う必要があり、一度しか定義したくない場合に便利です。これのより完全な例については、libiconvのコードとiconvユーティリティを参照してください。

+0

これは悪いです。なぜ使用しないのですか: "#define ELEMENT(x)x"そしてカンマを列挙型に追加しますか? – nilton

+1

考え方は、enumの内容はそれ自身別のマクロであるということです: '#define ALL_ELEMENTS(ELEMENT)ELEMENT(a)ELEMENT(b)ELEMENT(c)'。その後、特定の時刻に必要なものだけを '#define ELEMENT'してから、' ALL_ELEMENTS'マクロを呼び出します。 –

14

他の誰もが言っているように、コンマは必須ではありません。しかし、それはC99で新しくなりました(C89で許可されていませんでした)、次のバージョンのC++でも使用できます。あなたの列挙の最後の項目はコンマを持っている必要があることを、あなたのコーディングガイドラインに入れることができ、今

enum Items { 
    A, 
    B, 
    C, 
    LENGTH 
}; 

もう一つの根拠は「長さ」列挙子と通常の列挙子の違いを作ることです適用されますが、「長さ」項目の場合は表示されません。

これはまた、他の回答のように(マクロ/プリプロセッサを使用して)アイテムの自動生成に役立ちます。

+3

LENGTHイディオムがswitch(enum)の完全性を自動的にチェックするのは残念です。 –

7

標準C89では、最後のカンマは使用できません。完全停止。

これを許可するのは一般的な拡張です。特に、それはGCCによってサポートされていましたが、標準ではそれを認めていませんでした。

標準のC99では、最後のカンマは、配列と構造体のイニシャライザとの対称性のために使用できます。

6.7.2.2列挙型指定子

構文

enum-specifier: 
      enum identifieropt { enumerator-list } 
      enum identifieropt { enumerator-list , } 
      enum identifier 

末尾のカンマを許可する主な利点は、(Cソース)コードを簡単にマシンの生成を可能にすることである - あなたはありませんイニシャライザのリスト内の最後の(または多分、最初の)項目の特別なケースコードを書くことができます。したがって、YaccとLexのようなプログラムは、2つの名前を付けるほうがやや単純です。

0

その他の回答には言及していますが、標準準拠のC89とC++では末尾のカンマが許可されていないことを強調したいと思います。これは古いコンパイラや一般的でないコンパイラで移植性の問題になります。これと他の多くのC/C++の問題について説明する便利なリンクがあります:http://david.tribble.com/text/cdiffs.htm#C99-enum-decl

1

最後の末尾のカンマは必要ありません。

は、私は2つの理由から末尾のカンマを好む:

  1. クリーンgit diffs
  2. エディタで簡単に編集できます(Vimのddなど)。
関連する問題