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

时间:2009-04-27 09:06:06

标签: c syntax enums

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

即。是否需要VAL3之后的逗号?

enum { Val1, Val2, Val3, } someEnum;

将其留在/放出是否有任何副作用

由于

12 个答案:

答案 0 :(得分:36)

这不是必需的。 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的前两种形式,一种带有逗号,一种带有逗号。

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

enum {
    Val1,
    Val2,
    Val3,
} someEnum;

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

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

这可以比作常见的SQL:

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

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

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

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

答案 1 :(得分:15)

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

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

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

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

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

答案 2 :(得分:8)

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

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

在标准C99中,允许使用最后一个逗号,以便与数组和结构初始值设定项保持对称,它总是允许在最后一项上使用尾随逗号。

  

6.7.2.2枚举说明符

     

语法

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

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

答案 3 :(得分:4)

不,不是必需的。原因是,如果您不需要担心逗号是否存在,它会使剪切和粘贴代码变得更容易。

答案 4 :(得分:3)

不,不需要 - 实际上我会说它有不好的风格。

答案 5 :(得分:3)

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

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

答案 6 :(得分:2)

如果您使用宏,例如

,它是可选且有用的
#ifdef _FLAG
    #define OPTS opt_four, opt_five,
#else
    #define OPTS // none
#endif
enum {
  opt_one,
  opt_two,
  opt_three,
  OPTS
};

答案 7 :(得分:1)

不需要最后一个逗号。

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

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

#define ELEMENT(x) x,

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

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

,定义或数组初始化程序中的结尾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
};