148

Why do I receive the error "Variable-sized object may not be initialized" with the following code?

int boardAux[length][length] = {{0}};
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
helloWorld
  • 2,929
  • 7
  • 24
  • 19
  • As pointed out in the excellent answer by David Rodriguez: if length is a variable, you need memset, but if length is a compile-time constant, then the statement compiles just fine. – Casey Feb 11 '20 at 19:17
  • ffwd to 2020 -- `enum {length = 0xF } ; int boardAux[length][length] = {0}; ` – Chef Gladiator Aug 07 '20 at 08:11
  • 3
    making it a `const int` solved this issue for me. – Mote Zart Feb 12 '21 at 18:58
  • @MoteZart Did it? Given `const int length = 1; int boardAux[length][length] = {{0}};` `boardAux` is a variable-length array and `length` is *not* a constant expression. Remember, `const` just means read-only; it doesn't mean "constant". (`length` would be a constant expression in C++, which doesn't support variable-length arrays.) – Keith Thompson Sep 21 '21 at 08:41
  • @MoteZart I'm using VS Community 2022 and declaring: int expected_out[220 * a_const_int_var] = {0}; is not working in C language. What IDE, compiler and language did you use? – VMMF Nov 19 '22 at 00:34
  • Sorry guys. It was so long ago I can't recall the use case. I do know my comment was related predominately to the error msg, and my use-case might have been different than the OP. So adding const worked for whatever that was. Not at all helpful. I was using raw clang in terminal, with no IDE. – Mote Zart Nov 22 '22 at 23:58

10 Answers10

180

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) );
Community
  • 1
  • 1
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • I can use for this purpose malloc as well, what about the second question, I wrote it after Pavel's reply – helloWorld Jun 21 '10 at 08:10
  • @helloWorld: With stack allocated arrays, `printf( "%d", boardAux[1][2] )` compiles fine. The compiler knows the sizes and knows in what position in memory the (1,2)-th element is. If you use dynamic allocation the array is uni-dimensional and you must perform the math yourself: `printf("%d", boardAux[ 1*length + 2 ])` – David Rodríguez - dribeas Jun 21 '10 at 08:39
  • @AndreyT: Thanks for pointing the error in the `memset` call out. I have just corrected it. – David Rodríguez - dribeas Jun 21 '10 at 08:39
  • Why do I get this error in C99 compiler when I set the `length` to be `static`? In C++14 it works fine. – Silidrone Dec 18 '17 at 20:35
  • I want to know the reason why `malloc` is not required. – mazend Oct 21 '20 at 14:36
35

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
22

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";
Amitesh Ranjan
  • 1,162
  • 1
  • 12
  • 9
5

After declaring the array

int boardAux[length][length];

the simplest way to assign the initial values as zero is using for loop, even if it may be a bit lengthy

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}
5

Variable length arrays are arrays whose length is not known by the compiler at compile time. In your case length is a variable. I conclude this, because if length was a e.g. preprocessor macro defined as a literal integer your initialization would work. The first C language standard from 1989 did not allow variable length arrays, they were added in 1999. Still the C standard does not allow these to be initialized with an expression like yours (although one could argue that it could or should allow it).

The best way to initialize a variable array is like this:

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

memset is a very fast standard library function for initializing memory (to 0 in the above case). sizeof(boardAux) returns the number of bytes occupied by boardAux. sizeof is always available but memset requires #include <string.h>. And yes - sizeof allows a variable sized object as argument.

Note that if you have a normal array (not variable length) and just want to initialize the memory to zero you never need nested brackets, you can initialize it simply like this:

struct whatEver name[13][25] = {0};
3

The array is not initialized with the memory specified anf throws an error variable sized array may not be initialised I prefer usual way of initialization,

for (i = 0; i < bins; i++)
        arr[i] = 0;
Keth
  • 41
  • 3
  • 1
    Using `memset` is faster: `memset(arr, 0, bins * sizeof(int));` Also, I suspect your `for` loop should not be inclusive (i.e. `< bins` instead of `<= bins`). – rayryeng May 31 '21 at 20:25
  • Just for info to all other readers: memset is good only for int values. If you have to initialize, for example, the array with a float or a double, you will have a narrowing conversion from 'double/float' to 'int'. – SimoX May 04 '23 at 19:22
1

The question is already answered but I wanted to point out another solution which is fast and works if length is not meant to be changed at run-time. Use macro #define before main() to define length and in main() your initialization will work:

#define length 10

int main()
{
    int boardAux[length][length] = {{0}};
}

Macros are run before the actual compilation and length will be a compile-time constant (as referred by David Rodríguez in his answer). It will actually substitute length with 10 before compilation.

Sergey
  • 35
  • 3
0
int size=5;
int ar[size ]={O};

/* This  operation gives an error -  
variable sized array may not be 
initialised.  Then just try this. 
*/
int size=5,i;
int ar[size];
for(i=0;i<size;i++)
{
    ar[i]=0;
}
  • 2
    Welcome to Stack Overflow! Please read the guide on how to write a good answer: https://stackoverflow.com/help/how-to-answer Your current answer seems vague and doesn't have any explanation to it – gybandi May 22 '20 at 08:14
0

Prior to C23 it wasn't allowed to initialize a variable length array

int boardAux[length][length] = {{0}}; // Error

You therefore had to manually initialize it afterwards. Zero-initializing was often done with a memset.

Since C23, the initialization rules for variable length arrays have changed:

6.7.10 Initialization

  1. The type of the entity to be initialized shall be an array of unknown size or a complete object type. An entity of variable length array type shall not be initialized except by an empty initializer. An array of unknown size shall not be initialized by an empty initializer.

This means that, since C23, you may initialize a VLA, but only with an empty initializer to zero-initialize it.

int boardAux[length][length] = {}; // OK since C23
// memset( boardAux, 0, length*length*sizeof(int) ); // No longer needed
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
-4

Simply declare length to be a cons, if it is not then you should be allocating memory dynamically

Azizou
  • 35
  • 2
    I think you need to look up what const means! – Holger Sep 29 '16 at 17:21
  • @Holger: Are you sure? If the variable that holds the length (not the array itself, but the array length) is a constant, then the compiler knows the length to use to initialize the array. For example, "int length=5; int array[length];" gives the error but "**const** int length=5; int array[length];" compiles just fine. – Casey Feb 11 '20 at 19:11
  • 1
    @Casey: but `const int lenght=5; int array[length][length] = {{0}};` will not. – MestreLion Sep 07 '20 at 11:50
  • 1
    This is not correct. Declaring the length as a constant is not applicable here, and will not solve the problem that the OP described. – HomeworkHopper Jan 27 '22 at 19:28