为什么 C++支持堆栈上的动态数组吗?
在 C99 中这是合法的:
void f(size_t sz) {
char arr[sz];
// ...
}
然而,这个——动态大小的堆栈数组——已经在 C++ 中被删除,并且在 C++11 中没有看到返回。
AFAIK C++ 是在考虑到 C 兼容性的情况下创建的,所以我想知道一定有一些很好的论据不包括这个有用的功能,对吧?
我能想到的是:
优点
- 通过允许更智能来节省内存需要在堆栈上的数组大小(临时缓冲区?)。
- 更少的“智能指针”(或者更糟糕的是,手动引入错误的
删除[]
)和缓慢的堆分配。 - 与 C99 的兼容性。
缺点
- 允许人们轻松地在堆栈上分配太大的数组,从而导致难以调试的堆栈溢出。
- 对于编译器编写者来说更复杂。
那么,为什么他们在导入其他 C99 功能时没有包含它呢?
为了防止这个问题被认为是“主观的”或“没有建设性的”,我正在寻找委员会成员的引言或讨论该问题的讨论的链接——当然还有快速总结的奖励积分。
不要将其视为小马与仓鼠的讨论,而应将其视为一个历史问题,仅仅是对所考虑的优点和缺点的兴趣(如果有的话)。
编辑:正如 James McNellis 在下面的评论中指出的那样,C++ 在 C99 标准化可变长度数组之前就已经存在。您可能会将我的问题理解为:“他们为什么不添加它,也不会添加它?”。
In C99 this was legal:
void f(size_t sz) {
char arr[sz];
// ...
}
However, this - dynamically sized stack arrays - has been dropped in C++, and not seeing a return in C++11.
AFAIK C++ was made with C compatibility in mind, so I wondered There must be some very good argument of not including this useful feature, right?
All I could think of was this:
Pros
- Memory savings by allowing smarter array sizes that need to be on the stack (temporary buffers?).
- Less "smart pointers" (or worse, manual bug-introducing
delete []
's) and slow heap allocations. - Compatibility with C99.
Cons
- Allows people to easily allocate too large arrays on the stack giving hard-to-debug stack overflows.
- More complicated for compiler writers.
So, why did they didn't they include it when they imported other C99 features?
To prevent this from being closed as "subjective" or "not constructive", I'm looking for quotes from commitee members or links to discussions talking about the matter - with bonus points for a quick SO roundup of course.
Rather than seeing this as a Ponies vs Hamsters discussion, see it as a historical question, mere interest in the advantages and disadvantages that were considered (if at all).
EDIT: As James McNellis pointed out in the comments below C++ existed before C99 standardized variable-length arrays. You might read my question then as: "Why didn't and won't they add it?".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为,这是因为 C++ 提供了卓越的解决方案:
std::vector
和std::array
(C++11);尽管后者不是动态的,但它优于原始数组。无论您传递向量或数组给哪个函数,您始终可以知道大小。由于 C 无法提供这些解决方案,C99 提出了可变长度数组 (VLA)。它与常规数组有同样的问题:在将其传递给函数时,它会衰减为指针,并且您不再知道数组的大小。
正如Florian Weimer所问的此处在
comp.std.c++
处,如果 C++0x 允许 VLA,那么会发生什么下面的代码是什么意思?当向量模板的类型参数依赖于运行时已知的
n
时,编译器如何在编译时实例化向量模板?I think, it's because C++ provides superior solutions:
std::vector<T>
andstd::array<T,N>
(C++11); though the latter is not dynamic as such but it's superior to raw arrays. You can always know the size, no matter which function you pass the vector or array.Since C cannot provide these solutions, C99 came up with Variable Length Array (VLA). It has the same problem as regular arrays: it decays into a pointer on passing it to function, and you no longer know the size of the array.
And as Florian Weimer asked here at
comp.std.c++
that if C++0x allows VLA, then what would the following code mean?How is the compiler going to instantiate the vector template at compile-time when it's type argument depends on
n
which is known at runtime?此功能在很大程度上重复了 std::vector 的功能,只是它消耗的资源更有限(堆栈与堆空间)。因此,从语义角度来看,C++ 中实际上并不需要它。
有人可能会说,栈上分配可以提高效率(特别是在面对多线程时);但是,这也可以在 C++ 中使用自定义分配器在堆栈或堆上构建私有内存池来实现。这又比将内存放在堆栈上更灵活,实际上您可以创建一个自定义分配器,可以轻松地从堆栈内存缓冲区中划分出块。它与动态数组语义并不完全相同,但自定义分配器和 STL 容器的存在涵盖了您想要堆栈分配的大多数用例。
This functionality largely duplicates that of
std::vector
, except that it consumes a more limited resource (stack vs heap space). As such, there is not really any need for it in C++, semantics-wise.One could argue that on-stack allocation can improve efficiency (particularly in the face of multiple threads); however, this can also be achieved in C++ using custom allocators to build a private memory pool, either on the stack or heap. This is again more flexible than placing memory on the stack, and indeed you could create a custom allocator that carves chunks out of an on-stack memory buffer easily enough. It's not exactly the same as dynamic array semantics, but the existence of custom allocators and STL containers covers most use cases you'd want stack allocation.