为何C99中函数内外指定数组维度的编译结果不同?
两段代码编译结果不同的原因
首先要明确C99标准里的两个关键规则:
- const修饰的变量并非编译期常量:在C语言中,
const int DIM;仅仅是定义了一个只读变量,它的值要到运行时才能确定,和#define DIM 10这种预编译阶段就直接替换为固定数值的宏完全不是同一个概念。 - 可变长度数组(VLA)的作用域限制:C99引入了可变长度数组——也就是数组大小由运行时表达式决定的数组,但这类数组仅允许在块作用域(比如函数内部)声明,绝对不能放在文件作用域(全局范围)。
我们来拆解两段代码的差异:
- 第一段代码中,
int tab[DIM];是在main函数内部声明的。由于DIM是只读变量,这个数组属于可变长度数组,而C99允许块作用域内声明VLA,因此编译器可以正常通过编译。 - 第二段代码中,
int tab[DIM];被放在了文件作用域(全局位置)。文件作用域的变量属于静态存储期,而VLA只能是自动存储期(分配在栈上),同时C标准明确禁止在文件作用域声明“可变修改类型”(VLA就属于这类),所以编译器会抛出错误:error: variably modified tab at file scope。
至于用#define DIM 10能修复问题的原因很直观:预编译阶段会把所有DIM替换为10,此时数组大小是编译期确定的常量表达式,不管是在文件作用域还是函数内部,都是合法的固定大小数组,自然不会触发报错。
内容的提问来源于stack exchange,提问作者axel
相关产品推荐
相关产品推荐

