在数组大小的情况下,gcc 4.8.2和gcc 4.9.0的行为差异

SAC*_*YAL 0 c++ arrays g++

在Gcc 4.8.2版本之前,以下代码无法编译,因为数组大小不是编译时间常量.

#include<iostream>
using namespace std;

int f(){return 10;}
int main()
{
    int i=10;  
    int arr[f()]={}; //error 
}
Run Code Online (Sandbox Code Playgroud)

当我尝试在4.9及更高版本上运行类似的代码时,相同的代码已成功编译.

它是允许这样的代码的编译器还是它现在是标准的一部分?

注意:上面的代码无法编译直到clang 3.7.1

use*_*694 5

可变长度数组是C99功能,但允许作为GCC for C++的扩展.在C99中,初始化可变长度数组是非法的:

6.7.8/3要初始化的实体的类型应为未知大小的数组或不是可变长度数组类型的对象类型.

手册中没有说明在GCC中初始化VLA是否合法,因此您可以假设它是未定义的行为.但是,您还有另一个未定义行为的来源:f()没有return语句,因此程序中的任何内容都可能发生(分段错误和异常是我在GCC 4.9.0中得到的两个不同结果)

它在GCC 4.9.0中成功编译的原因只是开发人员可以回答的问题.提交错误报告.

推测:"运行时大小的数组"被提议添加到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;
     };
  }
Run Code Online (Sandbox Code Playgroud)

该类bad_array_length定义实现引发异常的对象类型,以报告尝试分配大小小于或等于零或大于实现定义的限制(8.3.4 dcl.array)的运行时绑定数组.

bad_array_length() noexcept;
Run Code Online (Sandbox Code Playgroud)

效果:构造类的对象bad_array_length. 备注:调用what()新构造的对象的结果是实现定义的.

文档指出,在GCC 5及更高版本中,现在支持常规VLA.如果是这种情况,则应拒绝代码.