为什么 C++ "fill" 可以初始化可变大小的数组?

why can C++ "fill" initialize a variable-sized array?

#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;
}

还可以

我想知道这个编译成功而前一个失败的原因

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

详细地说,当你在栈上分配内存时,在编译时必须知道大小。由于数组是方法的局部数组,它们将被放置在堆栈上。

VLA 不是 C++ 的一部分。它们作为扩展被一些编译器支持。它们来自 C99,并且在 C99 you cannot initialize VLA with = {0};. Some compilers (like GCC) go further and add support for such an initialization. In GCC this syntax can be used starting from version 4.9 中。 Clang 显然不支持它,也没有必要。

你的两个例子都不合法,因为 n 不是编译时间常量,标准 C++ 不允许数组初始化的非常量长度(但是 C 允许)。

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

您可以在 GCC 中启用它们,例如使用 -Wall -Wextra 和可选的 -Werror。如果你想让你的编译器严格遵守标准,也加上-pedantic

您可能想改用 std::vector and resize。如果是这样,您的代码将变为

#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;
}