要从堆栈或堆中为变量分配内存,变量的大小需要知道。 C++编译器可以自己决定如何分配内存,但是C++已经公开了他们希望C++编译器如何处理这种情况,因此C++ std要求编译器供应商发布他们的内存处理。这是通过sizeof运算符发生的。该运算符在编译时完全计算。数组大小的编译时间限制来自此要求。
int arr[10];
std::cout << sizeof(arr) << std::endl
因为每个变量和类型都支持sizeof,所以它们的大小需要在编译时在C++中计算。因此,变长数组在C++中是不可能的。
这个要求还有另一个非常重要的限制。原则上,C++编译器供应商可以计算C++程序堆栈所需的最大内存量(如果没有问题的话):对于递归函数,不能计算程序使用的堆栈大小,但对于其他任何情况,堆栈大小都可以通过执行以下操作来计算:
- 使用sizeof(a)用于在堆栈帧
- 总和的每个变量的变量的尺寸,以获取该堆栈帧
- 列表中的所有可能的堆栈所需的存储器量帧并计算其大小
- 挑选最大尺寸的调用堆栈
- 选择该大小作为程序堆栈的大小。
不幸的是,递归函数打破了整个方案。而且它需要全局程序的流程分析来重新识别哪些函数可能具有无限的调用堆栈。但是编译时sizeof运算符的限制很重要,否则我们的C++程序会随机用尽堆栈空间,导致崩溃和不稳定。这是不可接受的。因此每个变量和类型都支持编译时sizeof运算符。
VLA支持要求编译器可以生成代码,其中通常生成的偏移量作为结果机器代码的常量在运行时实际上是可修改的。符合标准的C++编译器通常无法做到这一点。 C决定添加这个支持,因此C编译器可以做到这一点。但在这个过程中,他们需要打破运营商规模。编译时不再可以计算大小。如在C标准中规定的VLA的支持有很大的问题:
- 你不能把VLA结构或类中
- VLA的基本上仅限于本地函数范围
这些问题已经解决在C++中通过std :: vector没有任何这些问题。
来源
2011-04-20 15:59:03
tp1
*但*:没有C++标准曾接受过C99的VLA,因此从技术上讲,在C++中接纳VLA的事实是'g ++'扩展。 – 2012-07-28 01:45:31