Variable Length Array in C++
Ping Zhou, 2023-04-23
经常用 C/C++的朋友都知道,C/C++里面声明变量或者数组,是由编译器在编译时分配在堆栈上的,例如这个例子:
int main() { int a; // 声明一个变量 int arr[10]; // 声明一个数组 return 0; }
这个例子里的变量 a
和数组 arr
都是在编译时在栈上已经分配好了空间,这个和我们用 malloc()
, new
在运行时分配空间不同,后者是分配在堆(heap)上。
因为这些声明的变量/数组是在编译时分配的,它们的大小必须在编译时就已知,也就是说不能在运行时才决定数组的大小:
int r = 1 + (rand() % 10); int arr[r]; // C++语言不允许这么声明,因为r编译时未知
但是最近用 C++的时候注意到一个神奇的事情,像上面这样不符合 C++语言规范的用法,也能编译通过并正常运行!例如:
#include <iostream> using namespace std; int main(int argc, char **argv) { int r; r = stoi(argv[1]); cout << "declaring array of size " << r << endl; // array的大小在运行时决定 int array[r]; for(int i = 0; i < r; i++) { array[i] = i; } return 0; }
在这个例子里,数组 array
的大小在运行时才确定(通过命令行参数),因此这显然不符合 C++语言规范。但是我用 gcc 和 clang 都能编译通过。
查了一下发现,这个叫做 Variable-Length Array (VLA) ,即“可变长数组”,是 C++的一个扩展(extension),不是语言的一部分,但目前主流的编译器包括 GCC,Clang,Visual C++都支持这个扩展。
要确定你的编译器是否支持这个扩展,可以查看这个宏: __STDC_NO_VLA__
,如果它是 1,表示编译器不支持 VLA 扩展。