2

So I was messing around with C code and I noticed something about the way that gcc and clang handle code.

If I declare an array in file scope using a variable size, clang compiles with no problem but gcc throws an error. My guess is that it has to do with which compiler flags are/are not enabled by default in gcc/clang, but I would be glad if someone could tell me exactly why this thing is happening and maybe suggest some online resource where I can learn more about this functionality.

Here is an arbitrary example of the code that throws the error -

typedef struct node{
    int data;
    struct node *next;
    struct node *prev;
}node;

const int N = 1000;
node *table[N]; // This is where the error is

int main() {
    return 0;

running clang example.c with no other flags compiles fine running gcc example.c with no other flags throws an error -

example.c:9:7: error: variably modified 'table' at file scope
    9 | node *table[N];
      |       ^~~~
ZarakshR
  • 21
  • 1
  • 2
    According to the C Standard variable length arrays may not have static storage duration. However compilers may have their own language extensions. Also there is no variable length array if the program is compiled as a C++ program. – Vlad from Moscow Feb 10 '21 at 19:57

2 Answers2

1

N looks like a constant, but it is not really. The const means « I swear that I won't change the value of this variable » (or the compiler will remind me!). But it does not mean that it could not change by another mean I don't see in this compilation unit; thus this is not exactly a constant.

gcc seems to be very strict with the standard, but using the option -pedantic makes clang emit a warning.

$ clang -o prog_c prog_c.c -pedantic
prog_c.c:12:14: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
double table[N];
             ^
1 warning generated.

$ clang -o prog_c prog_c.c -pedantic -std=c90
prog_c.c:12:13: warning: variable length arrays are a C99 feature [-Wvla-extension]
double table[N];
            ^
prog_c.c:12:8: warning: size of static array must be an integer constant expression [-Wpedantic]
double table[N];
       ^
2 warnings generated.

$ clang -o prog_c prog_c.c -pedantic -std=c99
prog_c.c:12:8: warning: size of static array must be an integer constant expression [-Wpedantic]
double table[N];
       ^
1 warning generated.
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
prog-fh
  • 13,492
  • 1
  • 15
  • 30
  • More generally, I think Clang may be treating static const-qualified nonvolatile objects with known values (not just declared here and defined elsewhere) as compile-time constants in other contexts too, not just array dimensions. – Eric Postpischil Feb 10 '21 at 20:09
0

Depending on the version of gcc you are using, it defaults to C90 (with some extensions), and variable-length arrays are not a part of C90.

If you specify -std=c99 or -std=c11, it should support VLAs.

However, per the C language definition, VLAs cannot have static storage duration (as an array declared at file scope does). So clang must be treating N as a constant expression (much like C++ does) and the array is fixed-length, not variable-length. So far I haven't found anything in the clang documentation that would indicate that, though.

Run both compilers with the options -std=c11 -pedantic and see if you don't get the same errors.

John Bode
  • 119,563
  • 19
  • 122
  • 198