c99之前既然不支持变长数组,那么下面这段代码为什么还能编译通过?
#include &
int main()
{
int n;scanf("%d
",n);
int a[n];
}
编译命令:gcc t.c -ansi -o t
gcc t.c -ansi -o t
c语言没有但是gcc能编译过的东西多了,譬如说({1;2;3;4;5})表达式。
-ansi等效于-std=c90,但是并没有禁止所有GNU扩展。你可以加上-Wpedantic来禁用GNU扩展。不过GNU也其实没有保证一定能检查出所有不符合ISO规范的的地方,因为那需要许多额外的工作,而GCC只是编译器没有这个打算成为标准验证工具。
对于编译器来说,int a[n];中的a是automatic variable,要注意他的lifetime。这种变数只保证在第一次refer之前必须已经allocated好了的,但是,并没有规定死是在什么时候分配。所以,在执行scanf的时候,你可以理解成还没有在call stack中为他分配空间。
基于这个特点,如果一个函数中有多个自动变数,你也不能假定他们在栈中的相对位置跟声明的时候是一致的。
还可以对比一下global的数组,或者函数中的static数组,就不允许int b[n];这样的写法,数组的大小不能是变数,因为global和static变数在process layout中,是放在data或者BSS段的,编译的时候就要确定好数组的大小和存放的位置。
综上,这是自动变数和静态变数在数组上面体现出来的区别。
是不是这样的?
gcc的ansi默认应该是99以上,而且还有他自己的扩展。你如果要体验「最纯正」,最「old school」的c,加上-pedantic参数如果没记错的话,或者转用gcc 2.95.3。
现在的gcc默认都是c11了。
改变n,数组的长度(size(a))并不会发生变化。