UP | HOME

Ping's Tech Notes

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 扩展。