GCC在new表达式中不支持大括号省略?C++初始化一致性疑问
GCC对
new表达式聚合初始化的大括号省略支持存在bug 你的理解完全正确,这段代码在C++14标准下是完全合法的,GCC拒绝编译的行为不符合标准要求,属于实现层面的bug。
先再明确问题场景中的测试代码:
struct S { int m; }; int main() { S s_arr[1]{0}; // GCC编译通过 S *s_new = new S[1]{0}; // GCC报错 int i_arr[1][1]{0}; // GCC编译通过 int (*i_new)[1] = new int[1][1]{0}; // GCC报错 return 0; }
标准规则梳理
根据C++14标准(GCC 6.x至9.x默认采用gnu++14标准):
- 聚合初始化的大括号省略规则:在8.5.1聚合初始化条款中明确规定,初始化聚合类型时,嵌套聚合的大括号允许省略——初始化器列表会被递归应用到嵌套聚合的成员上。比如
int arr[1][1]{0}等价于int arr[1][1]{{0}},S arr[1]{0}等价于S arr[1]{{0}},这也是GCC能接受s_arr和i_arr的原因。 new表达式的初始化规则:5.3.4 New条款第17点规定,new表达式创建对象时,初始化器遵循直接初始化规则,和自动变量的直接初始化逻辑完全一致。也就是说,new S[1]{0}应该和S s_arr[1]{0}采用相同的聚合初始化逻辑,允许省略嵌套大括号。
编译器行为对比
- Clang(6.0.0至9.0.0)正确实现了标准规则,能够正常处理
new表达式中省略大括号的聚合初始化。 - GCC(6.1至9.2)在处理自动数组时正确支持大括号省略,但对
new表达式中的数组类型(无论是自定义结构体数组还是多维数组),错误地要求必须显式写出嵌套大括号: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};
^
6.x/7.x版本针对多维数组还会额外抛出未实现提示:sorry, unimplemented: cannot initialize multi-dimensional array with initializer。
验证与结论
将初始化器改为{{0}}后,所有测试的GCC版本都能正常编译,这侧面印证了问题出在GCC对new表达式聚合初始化的大括号省略逻辑上——它没有把new的初始化规则和自动变量的初始化规则统一起来。
你已经查阅GCC Bugzilla未找到相关问题,建议可以提交新的bug报告,附上测试代码和标准依据,帮助GCC修复这个兼容性问题。
内容的提问来源于stack exchange,提问作者fefe
相关产品推荐
相关产品推荐

