我已经很久没有在基本的编译器中使用基本数组进行编程了,但是最近我看到了这样的数组声明:
int y;
cin>>y;
int z[y];
过去的编译器常常给出错误“数组的存储大小不是常量”。然后我发现了 C99 中的可变大小数组。我想知道他们是如何在内部运作的。这会使数组动态化吗?这个内存是在堆上分配的吗?这种绑定(bind)是否仍然是静态完成的?如果是这样的话。
最佳答案
Variable Length Array (VLA) 是 C99 的一个特性,但包括 gcc
在内的几个编译器支持VLA as an extension在C99 和gcc 之外和 clang在 C++ 中支持可变长度数组 作为扩展,即使这实际上是一个 C99 特性。
在两个gcc
和 clang
使用 -pedantic
构建flag 将在 C 中产生类似于以下内容的警告:
warning: variable length arrays are a C99 feature [-Wvla-extension]
和 C++ 中类似的东西:
warning: ISO C++ forbids variable length array ‘z’ [-Wvla]
通常的实现会在堆栈上分配VLA,因为它们会像对待其他自动变量一样对待它们,尽管标准通常不涉及堆栈或堆大多数情况下分配在堆栈上。
我们还可以从C99 draft standard中看出VLA 只是 6.7.5.2
节中数组声明的另一种变体数组声明符 4 段说(强调我的):
If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;124) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.
我们从段落 5 中看到它的大小在其生命周期内不会改变:
[...]The size of each instance of a variable length array type does not change during its lifetime.[...]
尽管 VLAs 和其他变量的主要区别是 sizeof 是评估 VLAs 的,否则它在编译时计算,来自 6.5.3.4
节sizeof 运算符 2 段:
[...]If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
关于c++ - 可变长度数组 VLA(静态绑定(bind)或动态),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20295734/