問題(來自lee77):
1 2 3 4 5 |
int main(void) { auto a = 1; return 0; } |
把如上所示的程式碼寫在副檔名為.c的檔案裡面,用MS Visual Studio 2012編譯器編譯的時候不會報錯。我一直認為,當你使用.c的副檔名時,編譯器會按照C語言的語法來進行編譯,而不是C++。而且,據我所知,不顯示定義型別的auto變數宣告只有從C++11標準之後才被允許,在C++11中auto的含義是宣告該變數的型別可以被初始化法式推匯出來的。
這是不是意味著我的編譯器不嚴格遵守C語言的標準,或者這段程式碼實際上在C語言中是正確的?
最佳答案(來自larsmans):
auto 是一個古老的C語言關鍵字,它的代表含義是 “區域性作用域”。 auto a
等價於 auto int a
,而且函式裡的變數定義預設就是區域性作用域的變數,所以在該例子中它也等價於int a
.
這個關鍵字(auto)事實上是 C語言的前身——B語言 遺留下來的,B語言沒有基本型別: 一切型別都是 int, pointer to int, array of int . (*) 這些型別的宣告只能是 auto
或者 extern
。C語言繼承了 “任何型別是int” 作為預設法則,所以你能用如下方法宣告整型:
1 2 3 |
auto a; extern b; static c; |
ISO C標準 拋棄了這個法則,但是當然有一些編譯器為了向後相容而接受這個法則。如果你還是覺得陌生,你應該明白有一個類似的的法則在下面語句中也生效:
1 |
unsigned d; // actually unsigned int |
上式的程式碼在現代的程式碼中是很常見的。
C++11 複用了這個關鍵字(auto),既然它的原始含義很少被C++程式設計師使用,所以在C++11中被複用來作為型別推導。 這樣的做法通常是安全的,因為”一切型別都是int”這個C語言的法則已經被C++98標準中被拋棄; 唯一可能不安全的用法是 auto T a
, 不過也沒人會這麼做。()
(*) 在B語言中的字串處理很有意思: 你會使用int陣列和包裝多個字元在int陣列的每個成員裡。B語言事實上就是不同語法的BCPL(BCPL的變種)。