【问题标题】:Why is an extra comma not allowed in a parameter list when it is allowed in a brace initialization?为什么在大括号初始化中允许在参数列表中使用额外的逗号?
【发布时间】:2015-05-19 21:45:45
【问题描述】:

跟进我的一个老问题 (Is there any relevance to an extra "," in the end of a brace initialization?)

函数声明和函数调用中的参数列表没有像大括号初始化那样对代码生成友好,是否有任何技术原因?

我的意思是:

没关系,多余的,被忽略:

int generated_array[] = {
  1,
  2,
  3,
};

为了保持一致性,允许这样做不是也有意义吗?

int someFunc(
  int v1,
  int v2,
  int v3,
){...}

int ret_val = someFunc(
  1,
  2,
  3,
);

我看不出它会如何使编译变得更复杂,但也许有一些我没有想到的东西。我猜它实际上会稍微简化它。

当然,有人会说它不如大括号初始化有用,但应该存在这样的情况,如果允许的话,代码生成至少会简单一点。

【问题讨论】:

  • 初始化列表中尾随逗号的理由是允许机器轻松生成大型静态数组。不过,实际上并没有机器生成大型函数参数列表的需要。
  • 一旦我们去那里,为了保持一致性,我们必须允许int a, b = 1, c = 6,;
  • @hacks 我在回答中指出的 C99 基本原理解释它不仅仅是一个语法规则。
  • 如果逗号操作符是这样工作的,那为什么不a = b + c + d +;呢?
  • @cleong 我猜这个区别只是历史原因,因为它允许机器生成初始化列表,这一定很常见。

标签: c++ c code-generation


【解决方案1】:

我们可以在 Rationale for International Standard—Programming Languages—C initializer-list 中找到允许尾随逗号的理由:

K&R 允许在初始值设定项的末尾使用尾随逗号 初始化列表。标准保留了这种语法,因为它 提供从初始化程序中添加或删除成员的灵活性 列表,并简化此类列表的机器生成。

此理由不适用于其他情况。

关于comp.lang.c++.moderated:Are comma-separated lists ending in a comma legal? 的讨论也引用了相同的理由。

【讨论】:

  • 我不知道你为什么认为这个理由不适用于函数参数。它可以灵活地从函数参数列表中添加或删除成员,并简化此类列表的机器生成(即使很少这样做)。
【解决方案2】:

初始化列表中尾随逗号的理由是允许机器轻松生成大型静态数组。这样,如果您碰巧需要编写一个生成 C 数组初始值设定项列表的程序,您可以编写如下内容:

printf("int arr[] = {");
for (int i = 0; i < N; i++) {
    printf("%d, ", i);
}
printf("};");

如果不允许尾随逗号,您必须确保它没有生成;老实说,虽然这并不难做到,但它只是丑陋且令人头疼。

不过,实际上并没有机器生成大型函数参数列表的必要,而且这些列表在没有尾随逗号的情况下看起来更好看,因此无需在函数参数和调用中允许相同的内容。

【讨论】:

  • 从代码生成的角度来看,我不明白为什么列表必须很大才能成为一个很好的功能。关键是它是可变大小的。
  • @Martin 它不必很大,它只是典型的。
  • 另外一个好处是在版本控制中你修改的行数更少,而且更容易自动合并。
  • 您可以使用文本编辑器轻松地在列表或函数调用中重新排序段。例如。 alt+上/下或 ctrl+shift+上/下。任何语言都应该允许使用尾随逗号。
【解决方案3】:

在我看来,这与以下事实有关:在 C 的早期,您可以在函数的声明或函数用空参数列表声明之前调用函数。在这种情况下,编译器从函数调用及其提供的参数中提取有关参数的信息。在这种情况下,结尾的逗号可以被认为是一个错误,因为不清楚编写调用的程序员的意图,也不清楚函数是否确实具有与参数数量相对应的参数数量。

当您使用初始化列表时,所有信息都在您眼前。你指定了多少个初始化器,这么多项目被初始化,或者这么多元素会有一个数组。

【讨论】:

    【解决方案4】:

    我似乎记得“很久以前在一个遥远的星系中”,C 语法允许使用尾随逗号来指定该函数具有可变数量的参数。后来改成, ...语法。

    如果我错了,请纠正我。

    【讨论】:

    • 天哪,如果我从未听说过它,那一定是非常很久以前了。例如,早于 =++= 含义相同。
    猜你喜欢
    • 2011-10-25
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    相关资源
    最近更新 更多