Search code examples
cgccc99c11variable-length-array

Variable length array in the middle of struct - why this C code is valid for gcc


There is some strange code using VLA (Variable Length Arrays) which is treated as Valid C (C99, C11) by gcc 4.6:

$ cat a.c
int main(int argc,char**argv)
{
  struct args_t{
     int a;
     int params[argc];        // << Wat?
                        // VLA in the middle of some struct, between other fields
     int b;
  } args;

  args.b=0;

  for(args.a=0;args.a<argc;args.a++)
  {
    args.params[args.a]=argv[0][0];
    args.b++;
  }
  return args.b;
}

This code compiled without warnings:

$ gcc-4.6 -Wall -std=c99 a.c && echo $?
0
$ ./a.out ; echo $?
1
$ ./a.out 2; echo $?
2
$ ./a.out 2 3; echo $?
3

Same for -std=c1x:

$ gcc-4.6 -Wall -std=c1x a.c && echo $?
0

But this does not work with Intel C Compiler or with Clang+LLVM:

$ icc a.c -o a.icc
a.c(5): warning #1361: variable-length array field type will be treated as zero-length array field type
       int params[argc];
                  ^
$ ./a.icc; echo $?
47

$ clang a.c -o a.clang
a.c:5:10: error: fields must have a constant size: 'variable length array in structure' extension will never be supported
     int params[argc];
         ^
1 error generated.

So:

  1. Why is this considered valid by GCC?
  2. If it is an extension of GCC, where is it described?
  3. Is it valid in C99 and C11 ISO Standards?

Solution

  • GCC does not allow it, compile with -std=c99 -pedantic-errors. A VLA inside a struct is apparently a (poorly documented) non-standard GNU C feature. See this.