Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't the size of a static array be made variable?

Tags:

arrays

c

static

gcc

Related but not quite duplicate as it discusses C++:
can we give size of static array a variable

I am defining an array in one of the child files as follows.

static int arr[siz];

Here siz is a global variable available to the child file. But the gcc compiler produces the following error :

<filename>: <line_num> : error : storage size of ‘arr’ isn’t constant

Why can't I define a static array of variable size ?

EDIT : This seems to be a problem only for static int type. If I change the variable type of arr from static int to int, the error goes away, even though the size of array is still dependent on a variable siz.

like image 791
Abhinav Avatar asked May 20 '12 17:05

Abhinav


People also ask

Can the size of an array be a variable?

Variable length arrays are also known as runtime sized or variable sized arrays. The size of such arrays is defined at run-time. Variably modified types include variable length arrays and pointers to variable length arrays. Variably changed types must be declared at either block scope or function prototype scope.

How do you change the size of an array that is static?

If you need to be resizing arrays, then use an ArrayList. Here's an example: ArrayList list = new ArrayList<Object>(); list. add(obj); Object obj2 = list.

Can you initialize array with variable size?

But, unlike the normal arrays, variable sized arrays cannot be initialized.

Can you modify a static array?

An array that is declared with the static keyword is known as static array. It allocates memory at compile-time whose size is fixed. We cannot alter the static array.


3 Answers

Since the size of the array you declare is not constant, what you have is an Variable Length Array(VLA). VLA are allowed by the c99 standard but there are some limitations associated with it. You cannot have an variable length array with static or extern storage class specifier.

You have an VLA with static storage specification and it is not allowed by the C99 Standard.

Reference:

c99 Standard: 6.7.5.2/8

EXAMPLE 4 All declarations of variably modified (VM) types have to be at either block scope or function prototype scope. Array objects declared with the static or extern storage class specifier cannot have a variable length array (VLA) type. However, an object declared with the static storage class specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.

So if you want a dynamic size array with static storage specifier you will have to use a dynamic array allocated on heap.

#define MAX_SIZE 256
static int* gArr;
gArr = malloc(MAX_SIZE * sizeof(int));

EDIT:
To answer your updated question:
When you remove the static keyword from the declaration, the storage specifier of the declared array changes from static to global, note the standard quote above, it clearly mentions the restriction that VLAs are not allowed with static and extern storage specification. Clearly, you are allowed to have an VLA with global storage specification, which is what you have once you remove the static keyword.

like image 139
Alok Save Avatar answered Oct 01 '22 23:10

Alok Save


You are allocating the array at compile-time, so the compiler has to know the array's size in advance. You have to declare siz as a constant expression before you declare arr, for instance:

#define siz 5

or

enum ESizes
{
    siz = 5
};

Alternatively, if you need to determine its size in run-time, you can allocate it on the heap by using malloc:

static int* arr;
arr = (int*)malloc(siz * sizeof(int))

EDIT: as eddieantonio has mentioned, my answer is valid for C89. In C99 it is allowed to declare arrays of variable size.

like image 44
Eitan T Avatar answered Oct 01 '22 23:10

Eitan T


You can't define any array of variable size. That's because arr[siz] makes the compiler (!) allocate memory for your array (well, the compiler creates a program, that .., but let's not stray into details). However, variables can be changed at runtime (!) which means the compiler has no chance of knowing how much memory to allocate.

What you can do is

static int* arr;
arr = (int*) calloc(siz,sizeof(int))

These lines result in a program that allocates memory at runtime, therefore it's exact size may be defined at runtime as well.

like image 29
user1129682 Avatar answered Oct 01 '22 23:10

user1129682