hackerrank - variable length array c



variable length arrays in C and initializing it in place (8)

This question already has an answer here:

C99 allows defining arrays with non-constant size, i.e. the size used to define an array can change on runtime. Code snippet to explain it would be,

void dummy_function1(unsigned int length) {

 char arrA[length];  //Allowed
 .
 .
}

However, it does not allow initializing it in place, i.e.

void dummy_function2(unsigned int length) {

 char arrA[length]={0}; //Not Allowed, compiler throws an error
 char arrB[10]={0};     //Allowed
 .
}

I do not understand, why is this difference in behavior for array which is variable length and the one which is constant length. In both cases, the array would be given memory when the function is invoked.

https://ffff65535.com


n is a variable unlike sizeof a / sizeof *a because latter is calculate at compile time.

int b[n] declares a variable length array. You can't initialize it by using initializer list. You can use a loop or memeset function to initialize all of its elements to 0.

memset(b, 0, sizeof(b));

Hypothesis: C is a medium-level language, and the standards committee did not want to include operations in the basic language (counting the library as separate) that perform amounts of work not determined at compile time.

All the basic operations of C that come to my mind at the moment (perhaps somebody will correct me) require only an amount of work determined at compile time: Calling a function, multiplying two numbers, assigning a structure to another, and so on. These can all be performed with a number of machine instructions executed that is fixed at compile time.

Even allocating space for a variable-length array requires only a compile-time amount of work: Calculate the size and subtract that from the stack pointer. In contrast, initializing all of that space requires an amount of work determined at run time. This is out of character for the C language.

Library routines may require amounts of work determined at run time, such as memset.


It looks like this is not allowed by the standard if we look at the C99 draft standard section 6.7.8 Initialization paragraph 3 says(emphasis mine):

The type of the entity to be initialized shall be an array of unknown size or an object type that is not a variable length array type.

As to why most likely because supporting initialization of a variable length array would require indeterminate amount of work at run-time.


This gives error:

int len;
scanf("%d",&len);
char str[len]="";

This also gives error:

int len=5;
char str[len]="";

But this works fine:

int len=5;
char str[len]; //so the problem lies with assignment not declaration

You need to put value in the following way:

str[0]='a';
str[1]='b'; //like that; and not like str="ab";

You receive this error because in C language you are not allowed to use initializers with variable length arrays. The error message you are getting basically says it all.

6.7.8 Initialization

...

3 The type of the entity to be initialized shall be an array of unknown size or an object type that is not a variable length array type.


You'll have to use memset:

memset(board, 0, sizeof board);

Constant size array initalization with sizeof

The first example works because sizeof a / sizeof *a is a constant expression, and it's OK to be used as array dimension.

In the second example, n is NOT a constant expression, so the compiler treats b as a definition of variable length array, the error is saying VLAs may not be initialized.


Initializing variable length array

VLAs cannot be initialized by any form of initialization syntax. You have to assign the initial values to your array elements after the declaration in whichever way you prefer.

C11: 6.7.9 Initialization (p2 and p3):

No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.