我正在处理一段旧代码(没有测试)。我无意中发现了几个宏里隐藏的一段代码。如果使用GCC的-Wvla
编译,则会生成警告。
这段代码类似于以下小程序的内容:
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;
}
编译时会发出警告:
$ 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]);
| ^~~~
问题的罪魁祸首是这个表达式:sizeof(entry_t[10 - argc])
。语法有点令人困惑。我认为一个临时匿名数组被创建,类型为entry_t
,包含 10-argc
个元素。然后它的大小被计算出来,并且这个数组会被丢弃。
我的问题如下:
- 我对代码的理解是否正确?
- 这个表达式与
sizeof(entry_t) * (10-argc)
有何不同?两者计算出相同的值,都没有防止下溢(当argc> = 10
时)。第二个表达式不使用变长数组,因此不会生成警告,并且在我看来更易于理解。
-Wvla
被添加到编译标志列表中更有分量。我更关心的是我是否正确理解了代码,因为sizeof(VLA type)
并不是我每天都能观察到的东西。下面的答案非常好地回答了我的疑虑! - Grigory Rechistov