在过去的几年里,我不怎么使用C。当我今天读这个问题时,我遇到了一些我不熟悉的C语法。

显然,在C99中,以下语法是有效的:

void foo(int n) {
    int values[n]; //Declare a variable length array
}

这似乎是一个非常有用的功能。是否曾经讨论过将它添加到c++标准中,如果有,为什么省略了它?

一些潜在的原因:

编译器供应商难以实现 与标准的其他部分不兼容 功能可以用其他c++构造来模拟

c++标准规定数组大小必须是常量表达式(8.3.4.1)。

是的,当然我意识到在这个玩具示例中可以使用std::vector<int> values(m);,但这是从堆中分配内存而不是堆栈。如果我想要一个多维数组,比如:

void foo(int x, int y, int z) {
    int values[x][y][z]; // Declare a variable length array
}

矢量版本变得相当笨拙:

void foo(int x, int y, int z) {
    vector< vector< vector<int> > > values( /* Really painful expression here. */);
}

片、行和列也可能分布在整个内存中。

看看comp. stdc++上的讨论,很明显这个问题很有争议,争论双方都有一些重量级人物。当然,std::vector并不总是更好的解决方案。


当前回答

似乎c++ 14中也可以使用:

https://en.wikipedia.org/wiki/C%2B%2B14#Runtime-sized_one_dimensional_arrays

更新:它没有进入c++ 14。

其他回答

最近在usenet上有一个关于这个问题的讨论:为什么c++ 0x中没有VLAs。

我同意那些似乎同意必须在堆栈上创建一个潜在的大数组的人,通常只有很少的可用空间,这是不好的。参数是,如果你事先知道大小,你可以使用静态数组。如果事先不知道大小,就会编写不安全的代码。

C99 VLAs可以在不浪费空间或调用未使用元素的构造函数的情况下创建小型数组,但它们将对类型系统带来相当大的更改(您需要能够根据运行时值指定类型-目前c++中还不存在这种功能,除了新的操作符类型说明符,但它们经过了特殊处理,因此运行时性不会逃脱新操作符的作用域)。

你可以使用std::vector,但它并不完全相同,因为它使用动态内存,并且让它使用自己的堆栈分配器并不完全容易(对齐也是一个问题)。它也不能解决同样的问题,因为vector是一个可调整大小的容器,而VLAs是固定大小的。c++动态数组提案旨在引入一个基于库的解决方案,作为基于语言的VLA的替代方案。然而,据我所知,它不会成为c++ 0x的一部分。

似乎c++ 14中也可以使用:

https://en.wikipedia.org/wiki/C%2B%2B14#Runtime-sized_one_dimensional_arrays

更新:它没有进入c++ 14。

为此使用std::vector。例如:

std::vector<int> values;
values.resize(n);

内存将在堆上分配,但这只会带来很小的性能缺陷。此外,不要在堆栈上分配大数据锁是明智的,因为它的大小相当有限。

这样的数组是C99的一部分,但不是标准c++的一部分。正如其他人所说,向量总是一个更好的解决方案,这可能就是为什么可变大小数组不在c++标准中(或在提议的c++ 0x标准中)。

顺便说一句,关于“为什么”c++标准是这样的问题,可以去Usenet新闻组comp. stdc++。

这是考虑包含在c++ /1x中,但被放弃了(这是对我前面所说的更正)。

因为我们已经有了std::vector来填充这个角色,所以它在c++中就没有那么有用了。