动态分配数组使用初始化列表时是否需指定大小?GCC与MSVC行为差异
关于动态数组分配省略大小的语法规则
你碰到的编译差异核心和C++标准的版本演进、编译器的兼容策略直接相关,不存在统一的“必须指定大小”的固定规则:
- 若编译使用C++11及更早的语言标准:动态分配数组的语法强制要求在
new后的方括号内填写合法的长度表达式,哪怕搭配初始化列表,new int[] {0, 1, 2}这种省略大小的写法属于标准明确禁止的非法语法,此时必须显式指定数组尺寸。 - 若编译使用C++14及更新的语言标准:标准专门新增了规则,允许在带初始化列表的动态数组分配语句中省略方括号内的大小值,编译器会自动从初始化列表的元素数量推导需要分配的数组总长度,此时两种写法都是完全合规的:
- 显式指定大小:
int *array { new int [3] {0, 1, 2} }; - 省略大小(C++14起合法):
int *array { new int [] {0, 1, 2} };
- 显式指定大小:
两款编译器行为差异的本质
这种表现差异不属于标准定义的实现特性,核心是两个编译器的语法判定逻辑不同:
- GCC的语法判定严格对齐编译时选定的标准版本:如果编译参数没有指定高版本C标准,或是当前使用的GCC版本默认的兼容基线是C11及更早版本,碰到
new int[] {0,1,2}这种C++14才纳入标准的写法,就会直接抛出语法错误。很多开发者碰到的这类报错,本质是编译环境的默认标准版本偏低,只要手动在编译参数里加上-std=c++14及以上版本的选项,GCC就能正常接受这种省略大小的写法,不存在语法上的硬限制。 - MSVC从早期版本开始,就把“带初始化列表时省略动态数组大小”的写法作为自有语法扩展支持:哪怕用户在编译选项里指定使用C11甚至更老的标准,MSVC也不会严格卡低版本标准的语法限制,不会对这种写法触发报错,相当于提前把后来C14标准纳入的特性做成了编译器默认兼容的扩展。
内容的提问来源于stack exchange,提问作者Mohammad Ali
相关产品推荐
相关产品推荐

