也许我不是来自这个星球,但在我看来,以下应该是一个语法错误:

int a[] = {1,2,}; //extra comma in the end

但事实并非如此。当这段代码在Visual Studio上编译时,我很惊讶,但我已经学会了不相信MSVC编译器,就c++规则而言,所以我检查了标准,它也是标准允许的。如果你不相信的话,语法规则可以参考8.5.1。

Why is this allowed? This may be a stupid useless question but I want you to understand why I am asking. If it were a sub-case of a general grammar rule, I would understand - they decided not to make the general grammar any more difficult just to disallow a redundant comma at the end of an initializer list. But no, the additional comma is explicitly allowed. For example, it isn't allowed to have a redundant comma in the end of a function-call argument list (when the function takes ...), which is normal.

那么,有什么特别的原因,这个多余的逗号是明确允许的吗?


当前回答

原因很简单:添加/删除行很容易。

想象下面的代码:

int a[] = {
   1,
   2,
   //3, // - not needed any more
};

现在,您可以轻松地向列表中添加/删除项目,而不必有时添加/删除后面的逗号。

与其他答案相反,我真的不认为生成列表的便性是一个有效的理由:毕竟,代码对最后(或第一行)行进行特殊处理是微不足道的。代码生成器只编写一次,并使用多次。

其他回答

我认为是为了便于开发人员使用。

int a[] = {
            1,
            2,
            2,
            2,
            2,
            2, /*line I could comment out easily without having to remove the previous comma*/
          }

此外,如果出于某种原因,你有一个为你生成代码的工具;该工具不需要关心它是否是初始化中的最后一项。

它允许每一行都遵循相同的形式。首先,这样可以更容易地添加新行,并让版本控制系统有效地跟踪更改,还可以更容易地分析代码。我想不出技术上的原因。

据我所知,允许这样做的原因之一是自动生成代码应该很简单;最后一个元素不需要任何特殊处理。

如果你使用一个没有指定长度的数组,vc++ 6.0可以自动识别它的长度,所以如果你使用"int a[]={1,2,};", a的长度是3,但最后一个还没有初始化,你可以使用"cout<

这样可以防止在长列表中移动元素导致的错误。

例如,让我们假设我们有一个这样的代码。

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Super User",
        "Server Fault"
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

它很棒,因为它展示了Stack Exchange网站的原始三部曲。

Stack Overflow
Super User
Server Fault

但它有一个问题。你看,这个网站的页脚在超级用户之前显示了服务器故障。最好在别人发现之前搞定。

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Server Fault"
        "Super User",
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

毕竟,移动线条并没有那么难,不是吗?

Stack Overflow
Server FaultSuper User

我知道,没有网站称为“服务器故障超级用户”,但我们的编译器声称它存在。现在,问题是C有一个字符串连接特性,它允许您编写两个双引号字符串并不使用任何东西将它们连接起来(类似的问题也会发生在整数上,因为- sign有多个含义)。

现在,如果原始数组的末尾有一个无用的逗号呢?线会移动,但这样的bug不会发生。像逗号这么小的东西很容易被漏掉。如果你记得在每个数组元素后面加一个逗号,这样的错误就不会发生。您不希望浪费4个小时调试某个东西,直到您发现逗号是问题的原因。