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

发布于 2024-07-18 12:57:30 字数 151 浏览 2 评论 0原文

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

Val3后面的逗号是必须的吗?

enum { Val1, Val2, Val3, } someEnum;

将其保留/保留有任何副作用吗?

Is the last comma required in a C enum declaration?

That is, is the comma after Val3 required?

enum { Val1, Val2, Val3, } someEnum;

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

趁年轻赶紧闹 2024-07-25 12:57:30

这不是必需的。 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 的存在只是为了让您不必在您的 SQL 之前添加 where第一个子句以及每个后续子句之前的 and。 您可以仅依靠 where 已经存在的事实,并对您添加的所有内容使用 and

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

任何像样的 DBMS 查询优化器都应该能够在进入数据库表之前删除这样的常量子句。

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

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.

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.

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:

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.

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.

Oo萌小芽oO 2024-07-25 12:57:30

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

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

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

现在,您可以将枚举中的最后一项应用逗号,但如果它是“长度”,则不需要应用逗号作为编码指南item - 它只是告诉有多少个项目。

正如其他答案所解释的那样,它还有助于自动生成项目(使用宏/预处理器)。

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.

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.

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

傻比既视感 2024-07-25 12:57:30

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

这是允许它的常见扩展; 特别是它得到了GCC的支持,但标准明确不允许。

在标准 C99 中,为了与数组和结构初始值设定项对称,允许使用最后一个逗号,而数组和结构初始值设定项始终允许在最后一项上使用尾随逗号。

6.7.2.2 枚举说明符

语法

 枚举说明符: 
              枚举标识符opt { 枚举器列表 } 
              枚举标识符opt { 枚举器列表 , } 
              枚举标识符 
  

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

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

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

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.

6.7.2.2 Enumeration specifiers

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.

折戟 2024-07-25 12:57:30

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
};

The trailing , in an enum definition or array initializer is optional, but quite useful, especially in lists spanning multiple lines. It is allowed since C99 for reasons of symmetry as it gives all lines the same structure for each item:

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

It makes it easier to generate array contents with scripts and avoids error prone situations where adding extra elements to an array but forgetting to add a comma might go unnoticed:

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

Adding extra items:

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

Notice the missing comma in the middle of the list: the compiler parses the third string as "WindowsLinux" and the bug does not generate a syntax error.

With the trailing , on each line, it is much easier to add and delete items without modifying other lines. It is even more useful if lines are compiled conditionally as in this example:

const char *osnames[] = {
    "CP/M",
    "MS/DOS",
    "Windows",
#ifdef __UNIX__
    "Linux",
    "OS/X",
#endif
};
风为裳 2024-07-25 12:57:30

不,这不是必需的。 原因是,如果您不需要担心逗号是否存在,那么它可以更轻松地剪切和粘贴代码。

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.

对风讲故事 2024-07-25 12:57:30

不,这不是必需的——事实上我想说,把它放在那里是一种糟糕的风格。

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

汹涌人海 2024-07-25 12:57:30

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

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

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
};
剩一世无双 2024-07-25 12:57:30

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

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

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.

顾冷 2024-07-25 12:57:30

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

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

  1. 干净的 git diff
  2. 使用基于行的命令(例如 Vim 的 dd)在编辑器中轻松进行编辑。

The last trailing comma is not required.

I prefer trailing commas for two reasons:

  1. Clean git diffs.
  2. Easy editing in editors with line-based commands (e.g. Vim's dd).
任谁 2024-07-25 12:57:30

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

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

沧笙踏歌 2024-07-25 12:57:30

不,这不是必需的,为了代码清晰起见应该将其省略。 它的存在/不存在没有影响。

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

我的黑色迷你裙 2024-07-25 12:57:30

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

#define ELEMENT(x) x,

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

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

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.

#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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文