【问题标题】:Array allocation in C++ on stack with varying length [duplicate]C ++中的数组分配在具有不同长度的堆栈上[重复]
【发布时间】:2013-07-31 11:55:10
【问题描述】:

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

【问题讨论】:

  • 按照目前的标准,这是不允许的。它是一个名为可变长度数组的编译器扩展。使用合适的编译标志,您的代码将无法编译。

标签: c++ visual-c++ g++ clang


【解决方案1】:

您正在查看 GCC 的 variable length arrays。这是 GNU 扩展,不是标准 C++。

【讨论】:

  • 我认为添加它不应该使用它是正确的,因为它不会被其他编译器编译。
【解决方案2】:

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

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

最后,一个类似的功能(但与 C99 的 VLA 不完全相同)在布里斯托尔的 C++ 委员会会议(2013 年 4 月)上获得批准,并在 C++14 的current draft 中。

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 的更多信息,请参阅 this DrDobb 的文章。

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

更新:在 Chigago 会议上,委员会决定从 C++14 中删除此功能,而是将其放在单独的文档中,Technical Specification (TS) on array Extendions (TS)。此外,TS 还包含模板类dynarray,它与运行时边界数组有些相关。

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

【讨论】:

    【解决方案3】:

    这是一个gcc extension,看起来像clang supports this in limited cases,虽然它是valid c99,但它不是标准的C++。在gccclang 中,您可以使用-pedantic 标志,它会在gcc 中给您这样的警告:

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

    clang 中喜欢这样:

    warning: variable length arrays are a C99 feature [-Wvla-extension]
    

    【讨论】:

      【解决方案4】:

      在某些情况下,您可以使用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

      【讨论】:

        猜你喜欢
        • 2020-01-05
        • 2015-02-20
        • 2011-12-01
        • 2023-03-30
        • 2014-12-14
        • 2021-05-10
        • 2016-01-06
        • 1970-01-01
        相关资源
        最近更新 更多