为什么悬空逗号仍然存在?

mmi*_*nus -1 c parsing

曾几何时,我在有关编译器的计算机科学课程中编写了一个 C 编译器。部分工作涉及使用Backus Naur Form ( BNF ) 中的 C 语法,如下所示。让我感到奇怪的是,初始化列表的语法允许列表以逗号结尾(所谓的悬空逗号)。我在我的编译器和其他编译器上尝试了它,并确认它是允许的。

例子:

<initializer> ::= <assignment-expression>
            | { <initializer-list> }
            | { <initializer-list> , }
Run Code Online (Sandbox Code Playgroud)

在C中:

int array[] = { 1, 2, 3, };
Run Code Online (Sandbox Code Playgroud)

我的问题:直到今天,悬空逗号仍然是 C 的一部分,其他语言似乎也是如此。为什么他们没有被移除?(假设它们没有任何“适当的”功能(我可能是错的),为什么它们传播到其他语言?)

eer*_*ika 9

为什么他们没有被移除?

我不知道是否考虑过这样的删除。我不知道为什么要考虑这样的删除。

更进一步,如果它们尚不存在,就有充分的理由添加它们。它们很有用。事实上,尾随逗号已在标准修订版中添加到以前不允许使用的其他语言列表中。例如枚举(C99、C++11)。此外,还有建议将它们添加到更多列表,例如成员 init 列表。我希望看到它们在函数调用中被允许,就像它们在其他一些语言中被允许一样。

允许尾随逗号的一个原因是更容易修改(更少的工作;更少的错误机会)和修改程序时清晰的差异。

这里有些例子...

没有尾随逗号的旧版本:

int array[] = {
    1,
    2,
    3
};
Run Code Online (Sandbox Code Playgroud)

新版本:

int array[] = {
    1,
    2,
    3,
    4
};
Run Code Online (Sandbox Code Playgroud)

差异:

<     3
---
>     3,
>     4
Run Code Online (Sandbox Code Playgroud)

旧版本带有逗号:

int array[] = {
    1,
    2,
    3,
};
Run Code Online (Sandbox Code Playgroud)

新版本:

int array[] = {
    1,
    2,
    3,
    4,
};
Run Code Online (Sandbox Code Playgroud)

差异:

>     4,
Run Code Online (Sandbox Code Playgroud)

  • 另一个类似的优点是移动线路一致。如果没有尾随逗号,如果最后一项发生更改,则必须更新逗号。例如,将“2,”移动到最后一个位置时。如果使用尾随逗号,则不会出现此问题。 (2认同)

Eri*_*hil 5

允许终端逗号很有用。给出一些列表:

int Codes[] =
{
    37,
    74,
    88,
};
Run Code Online (Sandbox Code Playgroud)

然后:

  • 对于列表的人工维护,我们可以轻松添加或删除行,而无需摆弄逗号。如果不允许使用终端逗号,则附加新行还需要编辑现有的前一行以添加逗号,删除最后一行也需要编辑前一行以删除其逗号。
  • 对于机器生成的列表,我们不需要在生成列表的循环中包含代码来以不同的方式处理最后一个列表项。