1

Why does the following work just fine with gcc c99

int a[] = {1,2,3};
int b[sizeof a / sizeof *a] = {0};

But this gives compilation errors

int n = sizeof a / sizeof *a;
int b[n] = {0};

Error

file.c:14:2: error: variable-sized object may not be initialized
file.c:14:2: warning: excess elements in array initializer [enabled by default]
file.c:14:2: warning: (near initialization for 'b') [enabled by default]
arynaq
  • 6,710
  • 9
  • 44
  • 74
  • 1
    `sizeof a / sizeof *a` is a compile time constant whereas `n` isn't (even though it's value is computed at compile time). – P.P Feb 13 '15 at 13:44
  • You are not allowed to [initialize a vla](http://stackoverflow.com/a/18854398/1708801) – Shafik Yaghmour Feb 13 '15 at 13:45
  • 1
    As long as the desired constant is in the range of `int` (and is, in fact, constant), a possible workaround (avoiding a VLA) is `enum { n = sizeof a / sizeof *a }; int b[n] = {0};` – mafso Feb 13 '15 at 13:52
  • @Lundin I still get the error. gcc 463 – arynaq Feb 13 '15 at 13:59

2 Answers2

3

n is a variable unlike sizeof a / sizeof *a because latter is calculate at compile time.

int b[n] declares a variable length array. You can't initialize it by using initializer list. You can use a loop or memeset function to initialize all of its elements to 0.

memset(b, 0, sizeof(b));
haccks
  • 104,019
  • 25
  • 176
  • 264
3

The first example works because sizeof a / sizeof *a is a constant expression, and it's OK to be used as array dimension.

In the second example, n is NOT a constant expression, so the compiler treats b as a definition of variable length array, the error is saying VLAs may not be initialized.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • Makes sense but seems illogical to me. I would hope the compiler is smart enough to figure out that n is constant. – arynaq Feb 13 '15 at 13:49
  • @arynaq: I don't know the reason why the standard doesn't allow it, but possibly it was because it introduces UB: `int b[n] = { 1, 2, 3 };` -- what if `n` is smaller than 3? (There already is UB anyway for VLAs if the size is 0 or negative, however.) – mafso Feb 13 '15 at 13:55