为什么悬挂逗号仍然存在?
Why are dangling commas still a thing?
曾几何时,我在有关编译器的计算机科学课程中编写 C 编译器。部分工作涉及在 Backus Naur Form (BNF) 中使用 C 语法,例如 this。令我感到奇怪的是,初始化列表的语法允许列表 以逗号 (所谓的悬挂逗号)结尾。我在我的编译器和其他编译器上试过了,并确认它是允许的。
示例:
<initializer> ::= <assignment-expression>
| { <initializer-list> }
| { <initializer-list> , }
在 C:
int array[] = { 1, 2, 3, };
我的问题:时至今日,悬挂逗号似乎仍然是 C 语言的一部分,其他语言也是如此。为什么他们没有被删除? (假设它们没有任何“适当的”功能(我可能是错的),为什么它们会传播到其他语言?)
Why weren't they removed?
我不知道是否考虑过这样的删除。我不知道为什么会考虑这样的删除。
更进一步,如果它们尚不存在,则有充分的理由添加它们。它们很有用。实际上,尾随逗号已在标准修订版中添加到以前不允许使用的其他语言列表中。例如枚举(C99、C++11)。此外,有人提议将它们添加到更多列表中,例如 member init list。我更希望看到它们在函数调用中被允许使用,例如它们在其他一些语言中被允许使用。
允许尾随逗号的原因是更容易修改(更少的工作;更少的错误机会)和修改程序时的差异。
这里有一些例子...
没有尾随逗号的旧版本:
int array[] = {
1,
2,
3
};
新版本:
int array[] = {
1,
2,
3,
4
};
差异:
< 3
---
> 3,
> 4
带尾随逗号的旧版本:
int array[] = {
1,
2,
3,
};
新版本:
int array[] = {
1,
2,
3,
4,
};
差异:
> 4,
允许使用结尾逗号很有用。给出一些列表:
int Codes[] =
{
37,
74,
88,
};
然后:
- 对于列表的人工维护,我们可以轻松地添加或删除行,而无需使用逗号。如果不允许使用终端逗号,则追加新行也需要编辑退出前一行以添加逗号,删除最后一行也需要编辑前一行以删除其逗号。
- 对于 machine-generated 列表,我们不需要在生成列表的循环中包含代码来区别对待最后一个列表项。
曾几何时,我在有关编译器的计算机科学课程中编写 C 编译器。部分工作涉及在 Backus Naur Form (BNF) 中使用 C 语法,例如 this。令我感到奇怪的是,初始化列表的语法允许列表 以逗号 (所谓的悬挂逗号)结尾。我在我的编译器和其他编译器上试过了,并确认它是允许的。
示例:
<initializer> ::= <assignment-expression>
| { <initializer-list> }
| { <initializer-list> , }
在 C:
int array[] = { 1, 2, 3, };
我的问题:时至今日,悬挂逗号似乎仍然是 C 语言的一部分,其他语言也是如此。为什么他们没有被删除? (假设它们没有任何“适当的”功能(我可能是错的),为什么它们会传播到其他语言?)
Why weren't they removed?
我不知道是否考虑过这样的删除。我不知道为什么会考虑这样的删除。
更进一步,如果它们尚不存在,则有充分的理由添加它们。它们很有用。实际上,尾随逗号已在标准修订版中添加到以前不允许使用的其他语言列表中。例如枚举(C99、C++11)。此外,有人提议将它们添加到更多列表中,例如 member init list。我更希望看到它们在函数调用中被允许使用,例如它们在其他一些语言中被允许使用。
允许尾随逗号的原因是更容易修改(更少的工作;更少的错误机会)和修改程序时的差异。
这里有一些例子...
没有尾随逗号的旧版本:
int array[] = {
1,
2,
3
};
新版本:
int array[] = {
1,
2,
3,
4
};
差异:
< 3
---
> 3,
> 4
带尾随逗号的旧版本:
int array[] = {
1,
2,
3,
};
新版本:
int array[] = {
1,
2,
3,
4,
};
差异:
> 4,
允许使用结尾逗号很有用。给出一些列表:
int Codes[] =
{
37,
74,
88,
};
然后:
- 对于列表的人工维护,我们可以轻松地添加或删除行,而无需使用逗号。如果不允许使用终端逗号,则追加新行也需要编辑退出前一行以添加逗号,删除最后一行也需要编辑前一行以删除其逗号。
- 对于 machine-generated 列表,我们不需要在生成列表的循环中包含代码来区别对待最后一个列表项。