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

时间:2011-09-18 01:04:22

标签: c++ stack standards dynamic-arrays

在C99中这是合法的:

void f(size_t sz) {
    char arr[sz];
    // ...
}

然而,这个 - 动态大小的堆栈数组 - 已经在C ++中被删除了,而没有在C ++ 11中看到返回。

AFAIK C ++在考虑C兼容性的情况下制作,所以我想知道必须有一些非常好的论据,不包括这个有用的功能,对吗?

我能想到的就是:

赞成

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

缺点

  • 允许人们在堆栈上轻松分配过大的数组,从而产生难以调试的堆栈溢出。
  • 编译器编写者更复杂。

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


为了防止这种情况被关闭为“主观”或“不具有建设性”,我正在寻找委员会成员的引用或讨论此事的讨论的链接 - 当然还有快速的SO综合报道的奖励积分。

不要将此视为 Ponies vs Hamsters 讨论,而是将其视为一个历史问题,仅仅关注所考虑的优势和劣势(如果有的话)。


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

2 个答案:

答案 0 :(得分:19)

我认为,这是因为C ++提供了卓越的解决方案:std::vector<T>std::array<T,N>(C ++ 11);虽然后者不是动态的,但它优于原始数组。无论您通过向量或数组传递哪种函数,都可以随时知道大小。

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

正如 Florian Weimer comp.std.c++询问here如果C ++ 0x允许VLA,那么下面的代码意味着什么?

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

如果 type参数依赖于运行时已知的n,编译器在编译时如何实例化矢量模板?

答案 1 :(得分:2)

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

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