Why can't the size of a static array be made variable?
Solution 1
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.
Solution 2
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.
Solution 3
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.
Abhinav
Updated on August 06, 2020Comments
-
Abhinav almost 4 years
Related but not quite duplicate as it discusses C++:
can we give size of static array a variableI 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 ofarr
fromstatic int
toint
, the error goes away, even though the size of array is still dependent on a variablesiz
. -
DCoder almost 12 yearsC99 permits Variable-Length Arrays, as long as they are not static and not extern. "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."
-
Abhinav almost 12 years@DCoder I am using gcc 4.3. Thanks for the constructive comment.
-
Abhinav almost 12 yearsThanks for the well researched answer.
-
Abhinav almost 12 years@user1129682 Sorry, I had to re-open the question. Please read the edited question.
-
Abhinav almost 12 yearsSo effectively, if I am using gcc-4.3, VLA's aren't allowed for extern and static type variables? This is what the user DCoder has replied as well in a comment in another reply.
-
Alok Save almost 12 years@Abhinav: Yes, You are correct. VLA's aren't allowed for variables with
extern
andstatic
type storage specification.You are using gcc-4.3 which comlies to c99 standard.Updated the answer to address you edited query. -
user1129682 almost 12 yearsThe basic problem is always what I mentioned in my answer: at compile time it is uncertain what the values at runtime are going to be and what effect the values may have. Per se, in a plain, simple and naive view, that's why accessing runtime-defined values at compile time yields an error. To keep things short: with logic and compiler magic this uncertainty can be removed and the compiler will make it work.
-
Nagev over 6 yearsThere is some ambiguity on the meaning of "constant", at least with my compiler (gcc 6.3.0). Even if I do
const size_t siz = 3;
which is clearly not variable and can be evaluated at compile time, I'd still get an error withstatic char arr[siz];
which seems rather limiting. By the way, in my case, I was trying to use sizeof() on a fixed string, for maintainability and self-documentation. -
Eitan T about 6 years@HeathRaftery You are absolutely correct (I had C++ in mind when writing this, forgetting that the question is about C). Example removed. Thank you for bringing this to my attention.