C枚举中的最后一个逗号是必需的吗?

时间:2021-12-29 01:25:58

Is the last comma required in a C enum declaration?

C枚举声明中是否需要最后一个逗号?

i.e. is the comma after VAL3 required?

即,是否需要VAL3后面的逗号?

enum{Val1, Val2, Val3,} someEnum;

Are there any side-effects of leaving it in/out

放进去/放出来有什么副作用吗

Thanks

谢谢

11 个解决方案

#1


36  

It's not required. Section 6.7.2.2 of C99 lists the syntax as:

这不是必需的。C99的6.7.2.2节列出语法如下:

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

Notice the first two forms of enum-specifier, one with the trailing comma and one without.

注意前面两种类型的enum-specifier,一种用逗号结尾,另一种不用。

One advantage I've seen to using it is in things like:

我发现使用它的一个优点是:

enum {
    Val1,
    Val2,
    Val3,
} someEnum;

where, if you want to add in (for example) Val4 and Val5, you just copy and paste the Val3 line without having to worry about adjusting commas.

如果您想要添加(例如)Val4和Val5,只需复制并粘贴Val3行,而不必担心调整逗号。

And, as pointed out in a comment, it can also be to simplify automated code generators so that they don't have to have special handling for the final value. They can just output every value followed by a comma.

而且,正如在一篇评论中指出的,它还可以简化自动代码生成器,使它们不必对最终值进行特殊处理。它们可以输出每个后跟逗号的值。

This can be likened to the oft-seen SQL:

这可以与常见的SQL进行比较:

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

In that case, the where 1=1 is there only so that you don't have to put a where before your first clause and an and before each subsequent one. You can just rely on the fact that the where is already there and just use and for all the ones you add.

在这种情况下,where 1=1只在这里,这样你就不必在第一个子句前加上where,在后面的每个子句之前加上and。你可以只依赖于已经存在的地方,以及你添加的所有内容。

Some people may think this reeks of laziness and they're right, but that's not necessarily a bad thing :-)

有些人可能认为这是懒惰的表现,他们是对的,但这并不一定是坏事

Any decent DBMS query optimiser should be able to strip out constant clause like that before going to the database tables.

任何合适的DBMS查询optimiser都应该能够在访问数据库表之前删除诸如此类的常量子句。

#2


14  

Like everyone else says, the comma is not required. But it's new in C99 (wasn't allowed in C89) and will be allowed in the next version of C++ too.

就像其他人说的,逗号不是必需的。但是它在C99中是新的(C89中是不允许的),在c++的下一个版本中也是允许的。

One other rationale is to make a difference between a "length" enumerator and a normal enumerator:

另一个基本原理是区分“长度”枚举器和普通枚举器:

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

Now, you can put into your coding guideline that the last item in your enumeration should have a comma applied, but not if it is a "Length" item - which just tells how many items there are.

现在,您可以将枚举中的最后一个项应用到编码指南中,但如果它是一个“Length”项,则不应用逗号——它只告诉有多少项。

It also helps for automatic generation of items (using macros/preprocessors) like other answers explain.

它还有助于自动生成项目(使用宏/预处理器),就像其他答案一样。

#3


7  

In standard C89, the last comma is not permitted. Full stop.

在标准C89中,最后一个逗号是不允许的。句号。

It was a common extension to allow it; in particular, it was supported by GCC, but the standard expressly disallowed it.

这是一个普遍的延伸;特别是,它得到了GCC的支持,但是标准明确禁止它。

In standard C99, the last comma is allowed, for symmetry with array and structure initializers, which always did allow the trailing comma on the last item.

在标准C99中,对于数组和结构初始值设定项的对称性,允许使用最后一个逗号,因为数组和结构初始值设定项总是允许在最后一个项目上使用尾逗号。

6.7.2.2 Enumeration specifiers

6.7.2.2枚举说明符

Syntax

语法

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

The primary advantage of permitting trailing commas is that it permits easier machine generation of (C source) code - you do not have to write special case code for the last (or, maybe, the first) item in the list of initializers. Hence, programs like Yacc and Lex, to name but two, can be slightly simpler.

允许拖尾逗号的主要优点是它允许更容易的机器生成(C源代码)代码——您不必为初始化器列表中的最后一个(或者,可能是第一个)项编写特殊的案例代码。因此,诸如Yacc和Lex之类的程序可以稍微简单一点。

#4


4  

No it's not required. The reason being, it makes it easier for the purposes of cut and paste code, if you don't need to worry about whether the comma is meant to be there or not.

不,这不是必需的。原因是,如果您不需要担心逗号是否应该在那里,那么出于剪切和粘贴代码的目的,它会更容易。

#5


3  

No it is not required - in fact I would say having it there is bad style.

不,它不是必需的——事实上,我会说有它有不好的风格。

#6


3  

As already stated it is not required. The reason that a trailing comma is supported is that it (assuming the items are laid out one to a line) it allows you to conveniently rearrange the order of items in an enumeration using cut/paste or drag/drop, and it also allows you to comment out the last item without producing a syntax error. Omitting the trailing comma is legal but loses these code maintenance advantages.

如前所述,它不是必需的。支持后面的逗号的原因是它(假设的提出一个物品线)它允许您方便地重新排列项目的顺序枚举使用剪切/粘贴或拖/下降,它还允许您注释掉最后一项没有产生一个语法错误。省略后面的逗号是合法的,但是丢失了这些代码维护的优势。

I'd forgotten but Nick is quite right. I too have exploited the trailing comma with compiler directives. Without it, the conditional code would have been a lot messier and harder to read.

我忘了,但尼克说得很对。我也使用了末尾的逗号和编译器指令。如果没有它,条件代码将变得更混乱,更难以阅读。

#7


2  

It's optional and useful, if say you use macro, e.g.

它是可选的和有用的,如果你使用宏,例如。

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

#8


1  

No, it's not required and should be omitted for code clarity. Its presence/absence has no effect.

不,它不是必需的,应该被省略,以便代码清晰。它的出现/缺席没有影响。

#9


1  

The last trailing comma is not required.

不需要最后一个逗号。

I prefer trailing commas for two reasons:

我喜欢用逗号结尾,有两个原因:

  1. Clean git diffs.
  2. 干净的git差别。
  3. Easy editing in editors with line-based commands (e.g. Vim's dd).
  4. 使用基于行的命令(例如Vim的dd)轻松编辑。

#10


0  

Its not required, infact some compilers complain if you add one. for instance Visual Studio 6.
One use for the comma is for creating enums using c macros.

它不是必需的,事实上,如果您添加一个编译器,一些编译器会抱怨。例如,Visual Studio 6。逗号的一个用途是使用c宏创建枚举。

#define ELEMENT(x) x,

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

This pattern is useful if you there are several things you need to do with the elements and only want to define them once. For a more complete example of this you can look at the code of the libiconv and the iconv utility.

如果您需要对元素做一些事情,并且只需要定义一次,那么此模式将非常有用。要获得更完整的示例,可以查看libiconv和iconv实用程序的代码。

#11


0  

Other answers mention it but I'd just like to highlight that the trailing comma is disallowed in standards-conforming C89 and C++, which makes it a portability issue with old or uncommon compilers. Here's a useful link that explains this and many other C/C++ issues: http://david.tribble.com/text/cdiffs.htm#C99-enum-decl

其他的答案也提到了,但我想强调的是,在符合标准的C89和c++中,后面的逗号是不允许的,这使它成为与旧的或不常见的编译器的可移植性问题。这里有一个有用的链接,可以解释这一点以及其他许多C/C+问题:http://david.tribble.com/text/cdiffs.htm#C99-enum-decl

#1


36  

It's not required. Section 6.7.2.2 of C99 lists the syntax as:

这不是必需的。C99的6.7.2.2节列出语法如下:

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

Notice the first two forms of enum-specifier, one with the trailing comma and one without.

注意前面两种类型的enum-specifier,一种用逗号结尾,另一种不用。

One advantage I've seen to using it is in things like:

我发现使用它的一个优点是:

enum {
    Val1,
    Val2,
    Val3,
} someEnum;

where, if you want to add in (for example) Val4 and Val5, you just copy and paste the Val3 line without having to worry about adjusting commas.

如果您想要添加(例如)Val4和Val5,只需复制并粘贴Val3行,而不必担心调整逗号。

And, as pointed out in a comment, it can also be to simplify automated code generators so that they don't have to have special handling for the final value. They can just output every value followed by a comma.

而且,正如在一篇评论中指出的,它还可以简化自动代码生成器,使它们不必对最终值进行特殊处理。它们可以输出每个后跟逗号的值。

This can be likened to the oft-seen SQL:

这可以与常见的SQL进行比较:

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

In that case, the where 1=1 is there only so that you don't have to put a where before your first clause and an and before each subsequent one. You can just rely on the fact that the where is already there and just use and for all the ones you add.

在这种情况下,where 1=1只在这里,这样你就不必在第一个子句前加上where,在后面的每个子句之前加上and。你可以只依赖于已经存在的地方,以及你添加的所有内容。

Some people may think this reeks of laziness and they're right, but that's not necessarily a bad thing :-)

有些人可能认为这是懒惰的表现,他们是对的,但这并不一定是坏事

Any decent DBMS query optimiser should be able to strip out constant clause like that before going to the database tables.

任何合适的DBMS查询optimiser都应该能够在访问数据库表之前删除诸如此类的常量子句。

#2


14  

Like everyone else says, the comma is not required. But it's new in C99 (wasn't allowed in C89) and will be allowed in the next version of C++ too.

就像其他人说的,逗号不是必需的。但是它在C99中是新的(C89中是不允许的),在c++的下一个版本中也是允许的。

One other rationale is to make a difference between a "length" enumerator and a normal enumerator:

另一个基本原理是区分“长度”枚举器和普通枚举器:

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

Now, you can put into your coding guideline that the last item in your enumeration should have a comma applied, but not if it is a "Length" item - which just tells how many items there are.

现在,您可以将枚举中的最后一个项应用到编码指南中,但如果它是一个“Length”项,则不应用逗号——它只告诉有多少项。

It also helps for automatic generation of items (using macros/preprocessors) like other answers explain.

它还有助于自动生成项目(使用宏/预处理器),就像其他答案一样。

#3


7  

In standard C89, the last comma is not permitted. Full stop.

在标准C89中,最后一个逗号是不允许的。句号。

It was a common extension to allow it; in particular, it was supported by GCC, but the standard expressly disallowed it.

这是一个普遍的延伸;特别是,它得到了GCC的支持,但是标准明确禁止它。

In standard C99, the last comma is allowed, for symmetry with array and structure initializers, which always did allow the trailing comma on the last item.

在标准C99中,对于数组和结构初始值设定项的对称性,允许使用最后一个逗号,因为数组和结构初始值设定项总是允许在最后一个项目上使用尾逗号。

6.7.2.2 Enumeration specifiers

6.7.2.2枚举说明符

Syntax

语法

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

The primary advantage of permitting trailing commas is that it permits easier machine generation of (C source) code - you do not have to write special case code for the last (or, maybe, the first) item in the list of initializers. Hence, programs like Yacc and Lex, to name but two, can be slightly simpler.

允许拖尾逗号的主要优点是它允许更容易的机器生成(C源代码)代码——您不必为初始化器列表中的最后一个(或者,可能是第一个)项编写特殊的案例代码。因此,诸如Yacc和Lex之类的程序可以稍微简单一点。

#4


4  

No it's not required. The reason being, it makes it easier for the purposes of cut and paste code, if you don't need to worry about whether the comma is meant to be there or not.

不,这不是必需的。原因是,如果您不需要担心逗号是否应该在那里,那么出于剪切和粘贴代码的目的,它会更容易。

#5


3  

No it is not required - in fact I would say having it there is bad style.

不,它不是必需的——事实上,我会说有它有不好的风格。

#6


3  

As already stated it is not required. The reason that a trailing comma is supported is that it (assuming the items are laid out one to a line) it allows you to conveniently rearrange the order of items in an enumeration using cut/paste or drag/drop, and it also allows you to comment out the last item without producing a syntax error. Omitting the trailing comma is legal but loses these code maintenance advantages.

如前所述,它不是必需的。支持后面的逗号的原因是它(假设的提出一个物品线)它允许您方便地重新排列项目的顺序枚举使用剪切/粘贴或拖/下降,它还允许您注释掉最后一项没有产生一个语法错误。省略后面的逗号是合法的,但是丢失了这些代码维护的优势。

I'd forgotten but Nick is quite right. I too have exploited the trailing comma with compiler directives. Without it, the conditional code would have been a lot messier and harder to read.

我忘了,但尼克说得很对。我也使用了末尾的逗号和编译器指令。如果没有它,条件代码将变得更混乱,更难以阅读。

#7


2  

It's optional and useful, if say you use macro, e.g.

它是可选的和有用的,如果你使用宏,例如。

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

#8


1  

No, it's not required and should be omitted for code clarity. Its presence/absence has no effect.

不,它不是必需的,应该被省略,以便代码清晰。它的出现/缺席没有影响。

#9


1  

The last trailing comma is not required.

不需要最后一个逗号。

I prefer trailing commas for two reasons:

我喜欢用逗号结尾,有两个原因:

  1. Clean git diffs.
  2. 干净的git差别。
  3. Easy editing in editors with line-based commands (e.g. Vim's dd).
  4. 使用基于行的命令(例如Vim的dd)轻松编辑。

#10


0  

Its not required, infact some compilers complain if you add one. for instance Visual Studio 6.
One use for the comma is for creating enums using c macros.

它不是必需的,事实上,如果您添加一个编译器,一些编译器会抱怨。例如,Visual Studio 6。逗号的一个用途是使用c宏创建枚举。

#define ELEMENT(x) x,

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

This pattern is useful if you there are several things you need to do with the elements and only want to define them once. For a more complete example of this you can look at the code of the libiconv and the iconv utility.

如果您需要对元素做一些事情,并且只需要定义一次,那么此模式将非常有用。要获得更完整的示例,可以查看libiconv和iconv实用程序的代码。

#11


0  

Other answers mention it but I'd just like to highlight that the trailing comma is disallowed in standards-conforming C89 and C++, which makes it a portability issue with old or uncommon compilers. Here's a useful link that explains this and many other C/C++ issues: http://david.tribble.com/text/cdiffs.htm#C99-enum-decl

其他的答案也提到了,但我想强调的是,在符合标准的C89和c++中,后面的逗号是不允许的,这使它成为与旧的或不常见的编译器的可移植性问题。这里有一个有用的链接,可以解释这一点以及其他许多C/C+问题:http://david.tribble.com/text/cdiffs.htm#C99-enum-decl