为什么Clang决定在C++中允许指定初始化器?

4

我曾以为C++已经取消了指定初始化器,而这只适用于C语言。然而,我发现一个简单的例子可以使用clang++编译并成功运行。

int main()
{
    int a[6] = { [4] = 29, [2] = 15 };
}

g++: https://rextester.com/AXIZ79197 (错误)

clang++: https://rextester.com/UYVHHP56966 (正常工作)

vc++: https://rextester.com/UCBEU10658 (错误)

g++和vc++都无法编译,而clang++却可以正常工作。值得一提的是,g++和vc++给出了不同的错误信息。vc++将指定的初始化器与lambda表达式混淆了。我猜这可能是因为g++是一个较旧的编译器,但我不确定。

问题:

  1. 为什么clang决定允许指定的初始化器,而g++和vc++没有?
  2. 这只是一个编译器bug还是有其他原因?

与 C 语言中的 VLA 类似的故事。 - Matthieu Brucher
你使用的是哪个“-std”版本? - taskinoor
3
@ConstantinosGlynos 不,可变长度数组不属于C++。大多数编译器支持它们,但这并不符合标准。 - Yksisarvinen
1
你可以使用-Wc99-extensions让clang警告你,或者使用-pedantic - t.niese
1
编译器是由人为人编写的工具。因此,如果扩展很有用,编译器会自行实现它。开发人员可以决定是否要遵守标准(以便他们的代码可以在其他编译器上编译),或者是否针对特定的工具链,以使用其扩展来完成一些酷炫的事情。 - StoryTeller - Unslander Monica
显示剩余11条评论
1个回答

10

使用-pedantic编译时,会生成以下警告:

source_file.cpp:3:18: warning: designated initializers are a C99 feature [-Wc99-extensions]
    int a[6] = { [4] = 29, [2] = 15 };
                 ^~~~~~~~
source_file.cpp:3:28: warning: designated initializers are a C99 feature [-Wc99-extensions]
    int a[6] = { [4] = 29, [2] = 15 };

很显然,默认情况下 clang++ 启用了 c99-extensions

这不是一个 bug,因为编译器可以选择提供额外的功能。 clang++ 的开发人员只是决定将其启用。如果我们不想使用这些功能,最好使用 -pedantic

有趣的是,在寻找相关信息时,我发现了Clang中的C++支持页面,其中“指定初始化程序”通过扩展被列为即将到来的提案的部分支持:

对于C++17之后的一些提议的实验性支持,暂时命名为C++2a

这篇文章是即将到来的标准的确切提案。因此,将来的C ++中可能会有指定的初始化程序。


有没有办法在g++和vc++中启用c99扩展,以查看它们是否能够编译上述代码? - Constantinos Glynos
@ConstantinosGlynos 抱歉,我不知道g++或vc++中是否有任何选项可以编译您发布的代码。也许其他人可以帮忙。 - taskinoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接