在Gcc 4.8.2版本之前,以下代码无法编译,因为数组大小不是编译时间常量。
#include<iostream>
using namespace std;
int f(){return 10;}
int main()
{
int i=10;
int arr[f()]={}; //error
}
当我尝试在4.9及更高版本上运行类似代码时,相同的代码已成功编译。
是允许此类代码的编译器还是现在标准的一部分?
注意:上述代码无法编译,直到 clang 3.7.1
答案 0 :(得分:5)
可变长度数组是C99功能,但允许作为GCC for C ++的扩展。在C99中,初始化可变长度数组是非法的:
6.7.8 / 3要初始化的实体的类型应为未知大小的数组或不是可变长度数组的对象类型 类型。
manual中未说明在GCC中初始化VLA是否非法,因此您可以假设它是未定义的行为。但是,您还有另一个未定义行为的来源:f()
没有返回语句,因此程序中的任何内容都可能发生(分段错误和异常是我在GCC 4.9.0中得到的两个不同结果)
它在GCC 4.9.0中成功编译的原因只是开发人员可以回答的问题。提交错误报告。
猜测:&#34;运行时大小的数组&#34;是proposed被添加到C ++ 14但没有削减。海湾合作委员会在4.9中实施了原始提案。我之前提到的例外是提案中的一个功能:
在18.6.2.2 new.badlength:
之前添加一个新部分班级
bad_array_length
namespace std { class bad_array_length : public bad_alloc { public: bad_array_length() noexcept; }; }
类
bad_array_length
定义了抛出的对象类型 实现报告尝试分配的异常 运算符数组,其大小小于或等于零或 大于实现定义的限制(8.3.4 dcl.array)。bad_array_length() noexcept;
效果:构造类
bad_array_length
的对象。 备注:在新构造的对象上调用what()
的结果是实现定义的。
文档指出,在GCC 5及更高版本中,现在支持just regular VLAs。如果是这种情况,则应拒绝该代码。