是否需要C enum中的最后一个逗号?

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

ie是VAL3要求后的逗号?

 enum { Val1, Val2, Val3, } someEnum; 

将其留入/取出是否有任何副作用

谢谢

这不是必需的。 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 

注意enum-specifier的前两种forms,一种是逗号,另一种是逗号。

我见过使用它的一个好处是:

 enum { Val1, Val2, Val3, } someEnum; 

其中,如果要添加(例如) Val4Val5 ,只需复制并粘贴Val3行,而不必担心调整逗号。

并且,正如评论中所指出的,它也可以简化自动代码生成器,以便它们不必对最终值进行特殊处理。 他们可以输出每个值后跟逗号。

这可以比作常见的SQL:

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

在这种情况下, where 1=1只是为了使您不必在第一个子句之前and之后的每个子句之前放置一个where 。 您可以依赖于已存在的位置,并且只使用您添加的所有内容。

有些人可能会认为这是懒惰的,他们是对的,但这不一定是坏事:-)

任何体面的DBMS查询优化器都应该能够在转到数据库表之前去掉像这样的常量子句。

像其他人一样,逗号不是必需的。 但它在C99中是新的(在C89中是不允许的)并且也将在下一版本的C ++中被允许。

另一个理由是在“长度”枚举器和普通枚举器之间做出改变:

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

现在,您可以在编码指南中加入枚举中的最后一项应该使用逗号,但如果它是“长度”项目则不会 – 这只是告诉它有多少项目。

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

在标准C89中,不允许使用最后一个逗号。 完全停止。

允许它是一个共同的延伸; 特别是,它得到了海湾合作委员会的支持,但该标准明确禁止它。

在标准C99中,允许使用最后一个逗号,以便与数组和结构初始化器对称,它始终允许在最后一项上使用尾随逗号。

6.7.2.2枚举说明符

句法

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

允许尾随逗号的主要优点是它允许更容易的机器生成(C源代码) – 您不必为初始化列表中的最后一个(或可能是第一个)项编写特殊的大小写代码。 因此,像Yacc和Lex这样的程序,仅举两个,可以稍微简单一些。

不,不是必需的。 原因是,如果您不需要担心逗号是否存在,它可以更容易地实现剪切和粘贴代码的目的。

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

如前所述,这不是必需的。 支持尾随逗号的原因是它(假设项目一行排列)它允许您使用剪切/粘贴或拖放方便地重新排列枚举中项目的顺序,它还允许您注释掉最后一项而不产生语法错误。 省略尾随逗号是合法的,但会失去这些代码维护优势。

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

如果您使用宏,例如,它是可选且有用的

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

最后一个尾随逗号不是必需的。

我更喜欢尾随逗号有两个原因:

  1. 清洁git差异 。
  2. 使用基于行的命令在编辑器中轻松编辑(例如Vim的dd )。

不,它不是必需的,应该省略代码清晰度。 它的存在/不存在没有效果。

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

 #define ELEMENT(x) x, enum MyElements { ELEMENT(a) ELEMENT(b) ELEMENT(c) }; 

如果您需要对元素执行多项操作并且只想定义一次,则此模式非常有用。 有关此更完整的示例,您可以查看libiconv和iconv实用程序的代码。

其他答案提到它,但我只是想强调,在符合标准的C89和C ++中不允许使用尾随逗号,这使得旧版或不常见的编译器成为可移植性问题。 这是解释此问题和许多其他C / C ++问题的有用链接: http : //david.tribble.com/text/cdiffs.htm#C99-enum-decl

enum定义或数组初始值设定项中的尾部是可选的,但非常有用,尤其是在跨越多行的列表中。 由于C99因为对称性而允许它,因为它为每个项目提供了相同的结构:

 enum DAY { MON = 1, TUE, WED, THU, FRI, SAT, SUN, }; 

它可以更容易地使用脚本生成数组内容,并避免容易出错的情况,即向数组添加额外元素但忘记添加逗号可能会被忽视:

 const char *osnames[] = { "CP/M", "MS/DOS", "Windows" } 

添加额外的项目:

 const char *osnames[] = { "CP/M", "MS/DOS", "Windows" "Linux", "OS/X" }; 

请注意列表中间缺少的逗号:编译器将第三个字符串解析为"WindowsLinux"并且该错误不会生成语法错误。

通过尾随,在每一行上,添加和删除项目更容易,而无需修改其他行。 如果有条件地编译行,则更有用,如下例所示:

 const char *osnames[] = { "CP/M", "MS/DOS", "Windows", #ifdef __UNIX__ "Linux", "OS/X", #endif };