C enum声明中是否需要最后一个逗号?
即。是否需要VAL3
之后的逗号?
enum { Val1, Val2, Val3, } someEnum;
将其留在/放出是否有任何副作用
由于
答案 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;
其中,如果您要添加(例如)Val4
和Val5
,则只需复制并粘贴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)
答案 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
};