C++中的数组在具有不同长度的堆栈上进行分配

Mor*_*bel 2 c++ g++ clang visual-c++

我很惊讶地发现可以在C++中为堆栈分配一个变长数组(例如int array[i];).它似乎在clang和gcc(在OS/X上)都能正常工作,但是MSVC 2012不允许它.

这个语言功能叫什么?它是官方的C++语言功能吗?如果是,那么哪个版本的C++?

完整示例:

#include <iostream>

using namespace std;

int sum(int *array, int length){
    int s = 0;
    for (int i=0;i<length;i++){
        s+= array[i];
    }
    return s;
}

int func(int i){
    int array[i]; // <-- This is the feature that I'm talking about
    for (int j=0;j<i;j++){
        array[j] = j;
    }

    return sum(array, i);

}

int main(int argc, const char * argv[])
{
    cout << "Func 1 "<<func(1)<<endl;
    cout << "Func 2 "<<func(2)<<endl;
    cout << "Func 3 "<<func(3)<<endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

DUm*_*man 6

您正在查看GCC的可变长度数组.这是一个GNU扩展,不是标准的C++.


Cas*_*eri 6

此功能称为可变长度数组或VLA.

它是C99标准(以及C11)的一部分,但C++ 11不支持.但是,正如您所看到的,一些编译器接受它作为扩展.

最后,在布里斯托尔的C++委员会会议上(2013年4月)批准了类似的功能(但与C99的VLA不完全相同),并且是当前的C++ 14 草案.

C99的VLA和C++ 14之间的两个主要区别如下:

void f(std::size_t n) {
    int a[n];
    unsigned int x = sizeof(a);
    // ...
    int matrix m[n][n];
}    
Run Code Online (Sandbox Code Playgroud)

在C99中,表达式sizeof(a)在运行时进行评估.在C++ 14中,这是非法的.此外,C++ 14不支持多维VLA.

有关C99的VLAS更多信息,请参见 DrDobb的文章.

有关C++ 14的运行时大小的数组的更多信息,请参阅N3639,这是在布里斯托尔批准的论文.

更新:在Chigago会议上,委员会决定从C++ 14中删除此功能,而是将其放在单独的文档中,即关于阵列扩展(TS)的技术规范(TS).此外,TS还包括模板类dynarray,该模板类与运行时边界的数组有些相关.

从C++ 14中删除它的主要原因是委员会希望在标准化这些功能之前从实现和用户体验中获得反馈.