2

我惊讶地发现可以在 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;
}
4

4 回答 4

6

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

于 2013-07-31T11:57:57.263 回答
6

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

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

最后,一个类似的特性(但与 C99 的 VLA 不完全相同)在布里斯托尔的 C++ 委员会会议(2013 年 4 月)上获得批准,并在当前的 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];
}    

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

有关 C99 的 VLA 的更多信息,请参阅DrDobb 的文章。

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

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

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

于 2013-07-31T12:37:05.217 回答
2

这是一个gcc扩展,虽然它是有效的,但它似乎clang supports this in limited cases不是标准的 C++ 。并且您可以使用该标志,它会在以下位置向您发出警告:c99gccclang-pedanticgcc

warning: ISO C++ forbids variable length array ‘array’ [-Wvla]

像这样clang

warning: variable length arrays are a C99 feature [-Wvla-extension]
于 2013-07-31T12:07:31.703 回答
2

在某些情况下,您可以使用constexpr(C++11) 作为解决方法:

constexpr int getArraySize (int factor) {
    return 2 * factor + 1;
}

int my_array[getArraySize(3)];

实际上在 C++14 中,这个限制不应该再存在了:http: //isocpp.org/blog/2013/04/n3639-runtime-sized-arrays-with-automatic-storage-duration

于 2013-07-31T14:08:16.553 回答