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))並不會發生變化。