Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

and got

error: variable-sized object may not be initialized

but

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

is ok

I want to know the reason why this one got compiled while the former failed.

like image 338
jin zhenhui Avatar asked Nov 25 '19 06:11

jin zhenhui


3 Answers

VLA are not part of C++. They are supported by some compilers as an extension. They come from C99, and in 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 apparently doesn't support it, and it doesn't have to.

like image 146
Evg Avatar answered Oct 09 '22 09:10

Evg


You can declare an array only with constant size, which can be deduced at compile time. variable n can be known only at runtime.

To elaborate, when you allocate memory on the stack, the size must be known at compile time. Since the arrays are local to the method, they will be placed on the stack.

like image 21
Maddy Avatar answered Oct 09 '22 09:10

Maddy


Neither of your examples is legal since n is not compile time constant and standard C++ doesn't allow non-const length for array initialisation (C does however).

The reason why your second example compiles is, that you address the seemingly only problem your compiler has with your first example, i.e. it is not initialized.

I recommend compiling with all compiler warnings enabled, which probably should be default anyway. You can enable them in GCC for example with -Wall -Wextra and optionally -Werror. If you want your compiler to strictly stick to the standard, add -pedantic, too.

You might want to use std::vector and resize instead. If that is the case, your code would become

#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;
}
like image 40
nada Avatar answered Oct 09 '22 08:10

nada