8

我对 C++ 比较陌生,从一开始我就被灌输了你不能做类似的事情

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

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

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

4

4 回答 4

19

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

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

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

于 2010-04-09T19:50:41.460 回答
5

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

于 2010-04-09T19:50:41.370 回答
3

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

  1. 邪恶的编译器编写者可能认为,让远离他们的编译器变得更加困难有助于延长寿命。
  2. 仁慈的编译器编写者可能认为,在他们能够以很少甚至不花钱的情况下为您提供更多选择是一件好事。
于 2010-04-09T19:52:50.490 回答
1

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

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

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

于 2010-04-09T20:07:01.627 回答