C++ int a[]={1,2,};允许使用奇怪的逗号。有什么特别的原因吗?

C++ int a[]={1,2,};允许使用奇怪的逗号。有什么特别的原因吗?,c++,syntax,grammar,language-lawyer,C++,Syntax,Grammar,Language Lawyer,也许我不是这个星球的人,但在我看来,以下应该是一个语法错误: int a[] = {1,2,}; //extra comma in the end 但事实并非如此。在VisualStudio编译此代码时,我感到惊讶,但我已经学会不相信C++的规则,所以我检查了标准,并且它也允许标准的 < /强>。如果你不相信我,你可以看8.5.1的语法规则 为什么允许这样做?这可能是一个愚蠢而无用的问题,但我想让你明白我为什么要问这个问题。如果这是一般语法规则的一个子案例,我会理解——他们决定不让一般语法变

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

int a[] = {1,2,}; //extra comma in the end
但事实并非如此。在VisualStudio编译此代码时,我感到惊讶,但我已经学会不相信C++的规则,所以我检查了标准,并且它也允许标准的<强> < /强>。如果你不相信我,你可以看8.5.1的语法规则

为什么允许这样做?这可能是一个愚蠢而无用的问题,但我想让你明白我为什么要问这个问题。如果这是一般语法规则的一个子案例,我会理解——他们决定不让一般语法变得更难,只是不允许在初始值设定项列表的末尾使用多余的逗号。但是不允许,额外的逗号是明确允许的。例如,函数调用参数列表的末尾不允许有多余的逗号(当函数采用
)时),这是正常的


那么,还有什么特别的原因可以明确地允许使用这个多余的逗号吗?

我一直认为它可以更容易地附加额外的元素:

int a[] = {
            5,
            6,
          };
就变成了:

int a[] = { 
            5,
            6,
            7,
          };

在以后的日期。

它使生成源代码变得更容易,也使编写可以在以后轻松扩展的代码变得更容易。考虑添加额外条目到:

所需的内容
int a[] = {
   1,
   2,
   3
};
。。。必须在现有行中添加逗号,然后添加新行。将其与三个后面已经有一个逗号的情况进行比较,您只需添加一行即可。同样,如果您想删除一行,您可以这样做,而不必担心它是否是最后一行,并且您可以重新排序行,而不必使用逗号。基本上,这意味着你对待线条的方式是一致的

现在考虑生成代码。类似于(伪代码):

输出(“inta[]={”);
对于(int i=0;i

无需担心您正在填写的当前项目是第一项还是最后一项。更简单。

如果您这样做会很有用:

int a[] = {
  1,
  2,
  3, //You can delete this line and it's still valid
};

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

想象一下下面的代码:

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*/
          }

此外,如果出于任何原因,您有一个为您生成代码的工具;工具不必关心它是否是初始化中的最后一项。

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

它使生成数组或枚举的代码生成器更容易

想象一下:

std::cout << "enum Items {\n";
for(Items::iterator i(items.begin()), j(items.end); i != j; ++i)
    std::cout << *i << ",\n";
std::cout << "};\n";

出于向后兼容性的原因,我认为允许使用尾随逗号。有很多现有的代码,主要是自动生成的,它在后面加了一个逗号。它使编写循环变得更容易,在最后没有特殊条件。 e、 g

对于每个(my_inits.begin()、my_inits.end(),

[](常量标准::字符串和值){std::cout在实践中,唯一不允许使用的语言是Javascript,它会导致无数的问题。例如,如果您从数组中间复制并粘贴一行,将其粘贴到最后,并且忘记删除逗号,那么您的站点将完全被IE访问者破坏


*理论上这是允许的,但Internet Explorer没有遵循标准,并将其视为一个错误

这对于机器来说更容易,即解析和生成代码。 这对人类来说也更容易,即通过一致性进行修改、注释和视觉优雅

假设C,你会写下面的内容吗

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    puts("Line 1");
    puts("Line 2");
    puts("Line 3");

    return EXIT_SUCCESS
}
#包括
#包括
内部主(空)
{
看跌期权(“第1行”);
看跌期权(“第2行”);
看跌期权(“第3行”);
返回退出成功
}
不。不仅因为final语句是一个错误,还因为它是不一致的。那么为什么对集合也要这样做呢?即使是在允许您省略最后分号和逗号的语言中,社区通常也不喜欢它。例如,Perl社区似乎不喜欢省略分号,除了一行程序。他们将其应用于com妈妈也是


不要在多行集合中省略逗号,因为你不会在多行代码块中使用分号。我的意思是,即使语言允许,你也不会这样做,对吗?

所有人都说添加/删除/生成行的方便性是正确的,但这种语法真正的亮点是在合并时将源文件放在一起。假设您拥有以下阵列:

int ints[] = {
    3,
    9
};
假设您已将此代码签入存储库

然后,您的好友对其进行编辑,并在末尾添加:

int ints[] = {
    3,
    9,
    12
};
同时对其进行编辑,并在开头添加:

int ints[] = {
    1,
    3,
    9
};
从语义上讲,这些类型的操作(添加到开头,添加到结尾)应该是完全合并安全的,并且您的版本控制软件(希望是git)应该能够自动合并。遗憾的是,情况并非如此,因为您的版本在9后面没有逗号,而您的好友的版本在9后面没有逗号。然而,如果原始版本后面有9,它们将自动合并

因此,我的经验法则是:如果列表跨越多行,请使用尾随逗号;如果列表位于一行,请不要使用逗号。

此外
int ints[] = {
    3,
    9
};
int ints[] = {
    3,
    9,
    12
};
int ints[] = {
    1,
    3,
    9
};
#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 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
char *available_resources[] = {
"color monitor"           ,
"big disk"                ,
"Cray"                      /* whoa! no comma! */
"on-line drawing routines",
"mouse"                   ,
"keyboard"                ,
"power cables"            , /* and what's this extra comma? */
};
int a [] = {
#ifdef A
    1, //this can be last if B and C is undefined
#endif
#ifdef B
    2,
#endif
#ifdef C
    3,
#endif
};
#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };
LIST_BEGIN
   LIST_ENTRY(1)
   LIST_ENTRY(2)
LIST_END
#define LIST_LAST_ENTRY(x) x