【问题标题】:Difference in the behavior of gcc 4.8.2 and gcc 4.9.0 in case of array size在数组大小的情况下,gcc 4.8.2 和 gcc 4.9.0 的行为差异
【发布时间】:2016-04-28 15:23:20
【问题描述】:

在 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

之前无法编译

【问题讨论】:

  • 这是 C 还是 C++? VLA 只是其中之一的标准。 GCC 无论如何都支持它们。
  • 它是一个变长数组,vla,语言是什么很重要,请选择一个

标签: c++ arrays g++


【解决方案1】:

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

6.7.8/3 要初始化的实体的类型应该是一个未知大小的数组或者一个不是变长数组的对象类型 输入。

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

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

推测:“运行时大小的数组”是 proposed 要添加到 C++14 中,但没有成功。 GCC 在 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。如果是这种情况,代码应该被拒绝。

【讨论】:

  • 我唯一关心的是,这段代码是如何在 4.9 版本上编译的,所以 f() 的返回类型对我来说并不重要。无论如何,我已经更新了它。
猜你喜欢
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 2019-03-26
  • 2014-08-14
  • 2015-01-18
  • 2020-01-18
  • 1970-01-01
相关资源
最近更新 更多