为什么C++不支持堆栈上的动态数组?

Why doesn't C++ support dynamic arrays on the stack?

在C99中,这是合法的:

1
2
3
4
void f(size_t sz) {
    char arr[sz];
    // ...
}

但是,这个动态大小的堆栈数组已经在C++中被删除,并且在C++ 11中没有看到返回。

在C++中,C++是用C语言兼容的,所以我想一定有一些很好的理由不包含这个有用的特性,对吧?

我能想到的就是:

赞成的意见

  • 通过允许栈上需要的更智能的数组大小(临时缓冲区?)来节省内存。.
  • 更少的"智能指针"(或者更糟的是,引入delete []的手动错误)和较慢的堆分配。
  • 与C99兼容。

欺骗

  • 允许人们容易地在堆栈上分配过大的数组,从而难以调试堆栈溢出。
  • 对于编译器编写者来说更复杂。

那么,为什么他们在导入其他C99功能时没有包含它呢?

为了防止这被关闭为"主观的"或"不建设性的",我正在寻找来自委员会成员的报价或讨论有关此事的链接-当然是一个快速的如此全面的加分。

与其把这看作是小马对仓鼠的讨论,不如把它看作是一个历史问题,仅仅是对所考虑的利弊(如果有的话)的兴趣。

编辑:正如James McNellis在下面的评论中指出的,C++存在于C99标准化可变长度数组之前。你可能会读到我的问题:"为什么没有,他们不会添加它?".


我认为,这是因为C++提供了优越的解决方案:EDCOX1×1和EDCOX1×2(C++ 11);尽管后者不是动态的,但它优于原始数组。无论传递向量或数组的函数是什么,都可以知道大小。

由于C不能提供这些解决方案,C99提出了可变长度阵列(VLA)。它与常规数组有相同的问题:它在传递给函数时会衰减为指针,而您不再知道数组的大小。

正如Florian Weimer在EDCOX1 3中所说的,如果C++0x允许VLA,那么下面的代码意味着什么?

1
2
int vla[n]; //n is known at runtime!
std::vector<decltype(vla)> v; //what does this mean?

当矢量模板的类型参数依赖于运行时已知的n时,编译器将如何在编译时实例化它?


除了消耗更有限的资源(堆栈与堆空间),此功能在很大程度上与std::vector的功能重复。因此,在C++中,语义上并不需要它。

可以认为,堆栈分配可以提高效率(特别是面对多个线程);然而,这也可以在C++中使用自定义分配器来在堆栈或堆上构建私有内存池。这比将内存放在堆栈上更灵活,实际上,您可以创建一个自定义的分配器,足够容易地将块从堆栈上的内存缓冲区中分割出来。它与动态数组语义并不完全相同,但是定制分配器和STL容器的存在涵盖了您希望进行堆栈分配的大多数用例。