GCC 不支持新表达式中的大括号省略号

GCC does not support brace elision in a new-expression

本文关键字:省略号 不支持 表达式 GCC      更新时间:2023-10-16

考虑这个程序:

struct S {
int m;
};
int main() {
S s_arr[1]{0};
S *s_new = new S[1]{0};
int i_arr[1][1]{0};
int (*i_new)[1] = new int[1][1]{0};
return 0;
}

我认为 main 函数中的所有四个变量都应该使用聚合初始化进行初始化。

但是,GCC 只接受s_arri_arr,但拒绝s_newi_new报告(Ubuntu 上的 g++ 8.3.0(:

test.cpp: In function ‘int main()’:
test.cpp:7:26: error: could not convert ‘0’ from ‘int’ to ‘S’
S *s_new = new S[1]{0};
^
test.cpp:9:38: error: array must be initialized with a brace-enclosed initializer
int (*i_new)[1] = new int[1][1]{0};
^
test.cpp:9:38: error: array must be initialized with a brace-enclosed initializer

(注意:最后一行重复由 G++ 生成(

我也在 godbolt 上测试过,从 6.1 到 9.2 的 gcc 版本都无法编译这个程序。6.x 和 7.x 版本还给出了消息:">抱歉,未实现:无法使用初始值设定项初始化多维数组"i_new

{0}更改为{{0}}可以解决在 godbolt 上测试的所有 GCC 版本(6.1 到 9.2(的s_newinew问题。我可以理解这一点,因为S[1]int[1][1]都是聚合类型,其元素类型是子聚合(S数组;数组数组(。但是,C++允许省略这些大括号,并且 GCC 接受s_arri_arr,其中省略了这些大括号。

另一方面,clang 6.0.0 到 clang 9.0.0 愉快地接受了原始程序。

在 C++14 的规范中(gnu++14 是 GCC 6.5/7.4/8.3/9.2 的默认值(,

5.3.4 新建/17

创建类型 T 的对象的新表达式按如下方式初始化该对象:

......

(17.2( — 否则,将根据 8.5 的初始化规则解释 new-initializer 以进行直接初始化。

新初始值设定项应解释为直接初始化。由于s_arri_arr也是直接初始化的,我认为它们应该以相同的方式解释,并且原始程序应该格式良好。

我在这里缺少什么,还是这是 GCC 中的错误?

我试图搜索GCC Bugzilla,但没有找到任何相关的内容。

是的,这绝对是一个错误。new表达式被定义为使用直接初始化规则([expr.new]/18.2(,大括号省略适用于所有聚合初始化的情况([dcl.init.aggr]/12(。

如果在搜索 bugzilla 后找不到错误,请提交错误。