【问题标题】:why can C++ "fill" initialize a variable-sized array?为什么 C++ 可以“填充”初始化一个可变大小的数组?
【发布时间】:2020-03-20 10:29:45
【问题描述】:
#include <iostream>
using namespace std;
void aa(int n) {
    int test[n] = {0};
}
int main() {
    aa(10);
    return 0;
}

得到了

error: variable-sized object may not be initialized

但是

#include <iostream>
using namespace std;
void aa(int n) {
    int test[n];
    fill(test,test+10,0);
}
int main() {
    aa(10);
    return 0;
}

没问题

我想知道这个编译失败的原因。

【问题讨论】:

  • 您使用的是哪个编译器版本?
  • Apple LLVM 版本 10.0.0 (clang-1000.10.44.2) @Evg
  • onlinegdb.com/SkNQ2eKhB 第一个代码也可以工作
  • 都不合法,因为 n 不是编译时间常数
  • 您可能想改用std::vectorresize

标签: c++ arrays stack clang++ variable-length-array


【解决方案1】:

VLA 不是 C++ 的一部分。一些编译器支持它们作为扩展。它们来自 C99,在 C99 中 you cannot initialize VLA 和 = {0};。一些编译器(如 GCC)走得更远,增加了对这种初始化的支持。在 GCC 中,可以从 version 4.9 开始使用此语法。 Clang 显然不支持,也没有必要。

【讨论】:

    【解决方案2】:

    你只能声明一个大小恒定的数组,这可以在编译时推导出来。变量n 只能在运行时知道。

    详细地说,当您在堆栈上分配内存时,大小必须在编译时已知。由于数组是方法的本地数组,因此它们将被放置在堆栈中。

    【讨论】:

    • 其实我很好奇为什么不能在运行时在栈上分配一个可变大小的数组
    • 我评论的第一行回答了你的问题
    • @jinzhenhui,这是当时C++的不幸限制。有proposals可以修复。
    • 非常感谢@Evg,这正是我想要的答案
    【解决方案3】:

    您的示例都不合法,因为 n 不是编译时常量,标准 C++ 不允许数组初始化使用非常量长度(但 C 允许)。

    您的第二个示例编译的原因是,您解决了您的编译器在第一个示例中似乎唯一的问题,即它没有被初始化。

    I recommend compiling with all compiler warnings enabled, which probably should be default anyway. 您可以在 GCC 中启用它们,例如使用-Wall -Wextra 和可选的-Werror。如果您希望您的编译器严格遵守标准,请添加-pedantic

    您可能想改用std::vectorresize。如果是这样的话,你的代码就会变成

    #include <vector>
    
    void aa(int n) {
        // 1st parameter: number of elements, 2nd: value of elements.
        std::vector<int> test(n, 0); 
        // test.resize(n, 0); // is also possible
        // std::fill(test.begin(), test.end(), 0); // is also possible
    }
    
    int main() {
        aa(10);
        return 0;
    }
    

    【讨论】:

    • 启用警告不会对第二个示例执行任何操作。您需要 Clang 和 GCC 的 -pedantic-pedantic-errors 标志来诊断 VLA 的使用。
    • 谢谢,实际上我只是想知道是否有任何原因使得在运行时无法在堆栈上分配可变大小的数组。
    • @jinzhenhui stackoverflow.com/a/1887178/4850111 回答为什么 VLA 不是标准 C++
    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2021-11-29
    • 2017-03-06
    相关资源
    最近更新 更多