Why Can't I Initialize a Variable-Sized Array

Why can't I initialize a variable-sized array?

  • The size of the array must be a constant integral expression.
  • An integral literal is a constant integral expression. (int arr[5];)
  • A constant integral variable initialized with a constant expression is a constant expression. (const int j = 4; const int i = j; int a[i];)

  • A constant variable initialized with a non-constant expression is not a constant expression

     int x = 4;  // x isn't constant expression because it is not const
    const int y = x; //therefore y is not either
    int arr[y]; //error)

C compile error: Variable-sized object may not be initialized

I am assuming that you are using a C99 compiler (with support for dynamically sized arrays). The problem in your code is that at the time when the compilers sees your variable declaration it cannot know how many elements there are in the array (I am also assuming here, from the compiler error that length is not a compile time constant).

You must manually initialize that array:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );

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.

Why can't I create an array with size determined by a global variable?

In C99, 6.7.8/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.

6.6/2:

A constant expression can be evaluated
during translation rather than runtime

6.6/6:

An integer constant expression
shall have integer type and shall only
have operands that are integer
constants, enumeration constants,
character constants, sizeof
expressions whose results are integer
constants, and floating constants that
are the immediate operands of casts.

6.7.5.2/4:

If the size is an integer constant
expression and the element type has a
known constant size, the array type is
not a variable length array type;
otherwise, the array type is a
variable length array type.

a has variable length array type, because size is not an integer constant expression. Thus, it cannot have an initializer list.

In C90, there are no VLAs, so the code is illegal for that reason.

In C++ there are also no VLAs, but you could make size a const int. That's because in C++ you can use const int variables in ICEs. In C you can't.

Presumably you didn't intend a to have variable length, so what you need is:

#define size 5

If you actually did intend a to have variable length, I suppose you could do something like this:

int a[size];
int initlen = size;
if (initlen > 5) initlen = 5;
memcpy(a, (int[]){1,2,3,4,5}, initlen*sizeof(int));

Or maybe:

int a[size];
for (int i = 0; i < size && i < 5; ++i) {
a[i] = i+1;
}

It's difficult to say, though, what "should" happen here in the case where size != 5. It doesn't really make sense to specify a fixed-size initial value for a variable-length array.

why can't I initialize the array like this?

This statement

int array[a]={0};

declares a Variable Length Array (VLA).

According to C Standard (6.7.9 Initialization)

3 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
.

The problem is that the compiler shall know the array size at compile time that to generate the code that initialize an array.

Consider an example

void f( size_t n )
{
int a[n] = { 1, 2, 3, 4, 5 };
//...
}

Here is a is a variable length array. Now as n can have any value then the number of initializers in the array definition can be greater than the size of the array. So this code breaks the Standard from another side because the number of initializers may not be greater than the number of elements of array. On the other hand if the number of initializers less than the number of elements of array then what to do in this case? Maybe the programmer did not mean that some elements shall be zero-initialized.

As for this declaration

int array[5]={0};

then there is no variable length array. The size of the array is known at compile time. So there is no problem

.

Initialized a pointer array in C - Variable sized object may not be initialized

Variable length arrays may not be initialized in their declarations.

You can use the standard string function memset to initialize the memory occupied by a variable length array.

For example

#include <string.h>

//...

int c = 15;
Struct *Pointer[c];

memset( Pointer, 0, c * sizeof( *Pointer ) );

Pay attention to that variable length arrays shall have automatic storage duration that is they may be declared in a function and may not have the storage specifier static.

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

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.

Problem with initializing variable-sized array?

int MAX = 20;
char input[MAX] = {'\0'};

input is a variable length array (VLA) and VLAs can't be initialized in standard C. Even if you const qualify MAX, it's still not a constant expression and thus input is still a VLA and thus it can't be initialized.

I saw a question with similar title and the person stated that he can only compile when he use constant variable as the size of array

That's probably said for C++. Because in C++ const-qualified variables are treated as constant expression. But that's not the case in C (this is mainly a historical discrepancy).

However,

char input[20] = {'\0'};

is an array and 20 is a constant expression and thus input can be initialized.

You could instead use:

  • a preprocessor macro (#define MAX 20)
  • an enum constant (e.g. enum { MAX = 20};)

that would qualify as a constant expression in C.

A general note on VLAs: beware that VLAs can be dangerous if you allocate a large arrays as they're typically allocated on stack and it could overflow. And there's no way to detect that overflow. So you'd want to avoid VLAs whenever you can (unless it's for a very small array, like in your example).



Related Topics



Leave a reply



Submit