为什么C ++可以“填充”初始化可变大小的数组?

时间:2019-11-25 06:55:20

标签: c++ arrays stack clang++ variable-length-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;
}

还可以

我想知道为什么在前一个失败的情况下编译该代码的原因。

3 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:1)

您只能声明一个大小恒定的数组,该大小可以在编译时推断出来。变量n仅在运行时已知。

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

答案 2 :(得分:1)

您的两个示例都不合法,因为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;
}