In C, const
should be read as read-only. It doesn't define a compile time.
const int a = 5;
Here a
, is not a constant expression as required by the C standard:
6.7.9 Initialization
4 All the expressions in an initializer for an object that has static or thread storage duration shall be constant
expressions or string literals.
So the error indicates you are using a C89/C90 compiler. You can read the input from user for a
and declare a variable length array, which is a C99-feature, which has automatic storage duration.
Using #define
is another way. But it's simply a textual replacement and defines an array with automatic storage duration. It's same as defining int arr[5];
yourself.
if you want to allocate memory on dynamic storage (commonly known as "heap"), you have to use malloc()
family functions, which will have lifetime thoughout the program execution until you call free()
on it.
(Note that this behaviour of const
is only in C. C++ differs in this and will work as you expected).
If I compile the code in C89, it fails with:
#include <stdio.h>
int main(){
const int a = 5;
int i;
int arr [a];
for (i = 0; i < 5; i++) {
arr[i] = i * 2;
}
printf("%d", arr[1]);
return 0;
}
$ gcc -Wall -Wextra -std=c89 -pedantic-errors test.c
test.c: In function âmainâ:
test.c:7:4: error: ISO C90 forbids variable length array âarrâ [-Wvla]
int arr [a];
^
because C89 doesn't support VLAs (Although gcc supports it as an extension even in C89/C90). So if you are using a compiler that doesn't support C99 then you can't use VLAs.
For example, visual studio doesn't fully support all C99 and C11 features. Although, Visual studio 2015 support most C99 features, VLAs are not one of them.
But the same code compiles in C99 and C11 without any problem:
$ gcc -Wall -Wextra -std=c99 -pedantic-errors t.c
$ gcc -Wall -Wextra -std=c11 -pedantic-errors t.c
It's because variable length arrays (VLAs) were added in C99. Note that VLAs have been made optional in C11 standard. So an implementation may not support VLAs in C11.
You need to test against __STDC_NO_VLA__
to check if VLAs are not supported by your implementation.
From 6.10.8.3 Conditional feature macros
__STDC_NO_VLA__
The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably
modified types.
I personally do not use VLAs as the allocation failure can't be portably found if the array size is reasonably large. E.g.
size_t size = 8*1024;
int arr[size];
In the above fragment, if arr
allocation failed, you won't know it until runtime. What's a "small enough" size for which the memory allocation is platform dependent. So on one machine, 1MB allocation may succeed and another it may fail and worse part is that there's no way to catch this failure.
Thus the use of VLAs is limited and can only be used with small arrays that you know will always succeed on a given platform. But in that I would simply hard-code the array size and take care of the boundary conditions.