I am working on a piece of legacy code (no tests). I stumbled upon a section hidden inside several macros. It generates a warning if compiled with GCC's -Wvla
.
The code in question is equivalent to what can be seen in this small program:
typedef struct entry {
unsigned index;
unsigned reserved;
unsigned value;
} entry_t;
int main(int argc, char **argv) {
long pa = 0;
long res = pa + sizeof(entry_t[10 - argc]);
return res;
}
When compiled, it gives out a warning:
$ gcc -g -Wvla repro-vla.c
repro-vla.c: In function ‘main’:
repro-vla.c:9:5: warning: ISO C90 forbids variable length array [-Wvla]
9 | long res = pa + sizeof(entry_t[10 - argc]);
| ^~~~
The culprit is of course this expression: sizeof(entry_t[10 - argc])
. The syntax is a bit confusing here. I believe a temporary anonymous array for 10 - argc
entries of type entry_t
is created, then its size is taken, and the array is discarded.
My questions are:
- Is my understanding of the code as it is written now correct?
- How is that expression any different from
sizeof(entry_t) * (10-argc)
? Both calculate the same value, and neither one does anything to guard against the underflow (whenargc >= 10
). The second expression does not use variable length arrays and as such won't generate the warning, and it is also easier to comprehend in my opinion.