Search code examples
cgccvariable-length-array

Gcc 4.8.2 default compiles and runs variable length arrays fine


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?


Solution

  • 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:

    GNU89 and GNU90

    [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] 
    

    C89

    [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]