为什么C ++允许不动态分配的可变长度数组?

时间:2010-04-09 19:48:58

标签: c++ standards-compliance dynamic-arrays

我对C ++比较陌生,从一开始就钻进了我不能做的事情

int x;
cin >> x;
int array[x];

相反,您必须使用动态内存。但是,我最近发现上面的编译(虽然我得到一个警告说它被ISO C ++禁止)。我知道如果标准不允许这样做显然是个坏主意,但我以前甚至不知道这是可能的。

我的问题是,为什么g ++允许在标准不允许的情况下动态分配的可变长度数组?另外,如果编译器可以这样做,为什么不是它在标准中呢?

4 个答案:

答案 0 :(得分:19)

在C99中,对C语言中添加了对可变长度数组(VLA)的支持。

由于对gcc的支持存在于gcc(支持C99),因此将它们的支持添加到g ++中相对简单。

也就是说,它是一个特定于实现的语言扩展,如果您希望代码可以移植,那么使用特定于实现的扩展并不是一个好主意。

答案 1 :(得分:5)

因为它在C99中受支持。我真的不能说为什么它不符合C ++标准。但是,它没有您想象的那么有用,因为它很容易导致(如果您不小心)堆栈溢出(因为它通常基于alloca,本身是非标准的)。另一个错误是返回一个指向动态数组的指针,该数组将立即超出范围。

答案 2 :(得分:3)

许多编译器接受并扩展标准。有两个基本原因:

  1. 邪恶的编译器编写者可能认为让他们更难摆脱编译器有助于延长使用寿命。
  2. 仁慈的编译器编写者可能会认为,当他们能够以很少甚至没有成本为自己提供更多选择时,这是一件好事。

答案 3 :(得分:1)

所有提及与他们在C中的原因都是正确的,尽管这个要求有限制。您的示例可以展示比C中所需的更灵活的支持(如果您使用scanf而不是cin实现它,将其放在.c文件中,并使用gcc)。

这几乎只是对alloca(分配auto)的隐式调用,它只是减少堆栈指针(增加堆栈大小)并将新堆栈指针复制到另一个寄存器,该寄存器用作指向已分配内存的指针。

不同之处在于不会在使用alloca创建的对象上调用构造函数和析构函数。