You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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标准):

  1. 聚合初始化的大括号省略规则:在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的原因。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:05:09