可变长度数组VLA(静态绑定或动态)
variable length arrays VLA (static binding or dynamic)
我已经很久没有用基本数组在基本编译器中编程了,但最近我看到了这样的数组声明:
int y;
cin>>y;
int z[y];
旧的编译器常常给出错误"数组的存储大小不是恒定的"。然后我发现了C99中的可变大小数组。我想知道他们内部是如何运作的。这会使数组具有动态性吗?这个内存是按堆分配的吗?这个绑定仍然是静态完成的吗?如果是,如何。
可变长度数组(VLA)是C99的一个功能,但包括gcc
在内的一些编译器支持VLA作为C99之外的扩展,gcc和clang都支持C++中的可变长度数组作为扩展,尽管这实际上是C99的一项功能。
在gcc
和clang
建筑中,使用-pedantic
标志将产生类似于C中以下内容的警告:
warning: variable length arrays are a C99 feature [-Wvla-extension]
类似于C++:
warning: ISO C++ forbids variable length array ‘z’ [-Wvla]
通常的实现将在堆栈上分配VLA,因为它们将像对待其他自动变量一样对待它们,尽管标准没有引用堆栈,或者在大多数情况下通常在堆栈上配置堆。
我们还可以从C99标准草案中看到,VLA只是6.7.5.2
数组声明器第4段中数组声明的另一个变体(emphasis mine):
如果大小不存在,则数组类型为不完整类型。如果大小是*而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用;124)这样的阵列仍然是完整的类型。如果大小是整数常量表达式,并且元素类型具有已知常量大小,则数组类型不是可变长度数组类型否则,数组类型为可变长度数组类型
我们从5段中看到,它的大小在其生命周期内不会改变:
[…]可变长度数组类型的每个实例的大小在其生存期内不会更改。[…]
尽管与VLA和其他变量的主要区别在于,sizeof是为VLAN评估的,而在其他情况下,它是在编译时计算的,从6.5.3.4
部分开始。sizeof运算符第2段:
[…]如果操作数的类型是可变长度数组类型,则计算操作数;否则,不计算操作数,结果为整数常量。
这会使数组具有动态性吗?
这取决于你如何定义"动态"。VLA当然不能增长或收缩,换句话说,一旦创建,就不能改变其大小。不过,它是动态的,从某种意义上说,它的长度在编译时是未知的。
这个内存是按堆分配的吗?
如何为VLA分配内存是特定于实现的。一般来说,VLA的内存是从调用方堆栈帧中的空间分配的。然后,当定义VLA的函数返回给调用方时,或者当VLA超出范围时,它会自动释放。
VLA最接近的关系是alloca()
函数,它几乎可以被认为具有相同的效果,至少在C中是这样。假设编译器以与alloca()
相同的方式实现VLA,则可以认为这两个数组在C:中在技术上是相同的
int *a = alloca(sizeof(int) * N);
int b[N];
然而,VLA具有更紧凑、更方便的语法。但最重要的是,VLA本质上有一个自动存储持续时间,并使编译器可以更自由地决定是在离开声明数组的范围时销毁/释放数组,还是在从函数返回时销毁/解放数组。
这在C++等语言中变得非常重要,因为编译器实现了RAII习惯用法,并且必须保证在退出对象的作用域时以自动存储持续时间销毁对象。
然而,请注意,VLA目前不是C++语言的一部分,而是由编译器作为非标准扩展实现的
简单回答:它通过增加堆栈指针来保留堆栈上的空间。
- 视觉studo 2019中的漫画和静态/动态绑定
- 创建.so时绑定动态库
- 如何使用泛型在 C# 中将类型静态绑定在一起(如在 TypeToType <T>中)?
- 尽管模板是静态绑定的,但旧代码的对象文件为什么以及如何使用使用通用编程范式的新代码
- 可变长度数组VLA(静态绑定或动态)
- 静态绑定期间C++和 Ada 的差异
- 是否有一个模板可以生成类的静态/动态绑定版本
- C++ 静态和动态绑定行为
- 我应该怎么做才能看到静态和动态绑定的作用?[C++]
- C++中的矢量容器和静态绑定
- boost::绑定动态参数
- 具有静态绑定成员函数指针的可变模板的多个专业化
- C++中数组的静态绑定检查
- 如何在Code::Blocks中将静态库绑定到动态库中
- 静态/动态范围、输入绑定
- 在C++中,动态数组与静态绑定数组有何不同
- c++多态性:为什么即使类型很明显,静态绑定也是不可能的
- 动态绑定、静态绑定和延迟绑定的区别是什么?
- 为什么有些语言更喜欢静态方法绑定而不是动态方法绑定
- 在C++中,如果成员函数是虚拟的,什么时候可以使用静态绑定