In C programming I came across a situation where I accidentally initialized an array with variable size and it worked. I did a bit of research and apparently variable length arrays are available from C99 compilation. Apparently, GCC 4.8.2's default compile option is C98.
Here is the code I used to test:
#include "stdio.h"
#include "stdlib.h" // rand(), srand()
#include "time.h"
void printArray(const char* c) {
// impossible to get size of c because it returns pointer size
int array[sizeof(c)/sizeof(char)];
int i;
for(i=0; i<(sizeof(c)/sizeof(char))-1; i++) {
int fill=-1;
if(c[i]=='a')
fill = 0;
else if(c[i]=='b')
fill = 1;
array[i]=fill;
}
printf("contents of array in binary: \n");
for(i=0; i<(sizeof(c)/sizeof(char))-1; i++) {
printf("%d, ", array[i]);
}
printf("\n");
}
void printRandomArray() {
srand(time(NULL));
// variable length array is possible using C99
int array[rand()%10];
int i;
printf("contents of random array: \n");
for(i=0; i<(sizeof(array)/sizeof(int)); i++) {
array[i]=rand()%10;
printf("%d, ", array[i]);
}
printf("\n");
}
int main(int argc, char* argv[]) {
char c[]="abbabbabbaababababababb";
printArray(c);
printRandomArray();
return 1;
}
printRandomArray() shouldn't work because I compiled using GCC 4.8.2 default which is C98 but it works. Could anybody explain to me why this is the case?
So GCC supports two different versions of C89. It supports c89
, and gnu89
. The latter means that a number of gcc extensions are enabled.
The default standard language for GCC 4.8.2 is gnu90
, which is identical to gnu89
. [see gcc documentation]
Let's look at the different warnings / errors we get when we use those different languages:
[2:10pm][wlynch@apple /tmp] /opt/gcc/4.8.2/bin/gcc asd.c
[2:10pm][wlynch@apple /tmp] /opt/gcc/4.8.2/bin/gcc -std=gnu89 asd.c
[2:10pm][wlynch@apple /tmp] /opt/gcc/4.8.2/bin/gcc -std=gnu90 asd.c
[2:10pm][wlynch@apple /tmp]
[2:10pm][wlynch@apple /tmp] /opt/gcc/4.8.2/bin/gcc -std=c89 asd.c
asd.c:2:21: warning: extra tokens at end of #include directive [enabled by default]
#include "stdlib.h" // rand(), srand()
^
asd.c: In function ‘printArray’:
asd.c:6:5: error: expected expression before ‘/’ token
// impossible to get size of c because it returns pointer size
^
asd.c:15:9: error: ‘array’ undeclared (first use in this function)
array[i]=fill;
^
asd.c:15:9: note: each undeclared identifier is reported only once for each function it appears in
asd.c: In function ‘printRandomArray’:
asd.c:26:5: error: expected expression before ‘/’ token
// variable length array is possible using C99
^
asd.c:30:24: error: ‘array’ undeclared (first use in this function)
for(i=0; i<(sizeof(array)/sizeof(int)); i++) {
^
[2:10pm][wlynch@apple /tmp] /opt/gcc/4.8.2/bin/gcc -std=gnu89 asd.c
[2:10pm][wlynch@apple /tmp]
If we fix those errors, and then also compile with -pedantic
, we will see the diagnostic that you are looking for:
[2:28pm][wlynch@apple /tmp] /opt/gcc/4.8.2/bin/gcc -std=c89 -pedantic asd.c
asd.c: In function ‘printRandomArray’:
asd.c:27:5: warning: ISO C90 forbids variable length array ‘array’ [-Wvla]
int array[rand()%10];
^
asd.c:27:5: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]