要從堆棧或堆中爲變量分配內存,變量的大小需要知道。 C++編譯器可以自己決定如何分配內存,但是C++已經公開了他們希望C++編譯器如何處理這種情況,因此C++ std要求編譯器供應商發佈他們的內存處理。這是通過sizeof運算符發生的。該運算符在編譯時完全計算。數組大小的編譯時間限制來自此要求。
int arr[10];
std::cout << sizeof(arr) << std::endl
因爲每個變量和類型都支持sizeof,所以它們的大小需要在編譯時在C++中計算。因此,變長數組在C++中是不可能的。
這個要求還有另一個非常重要的限制。原則上,C++編譯器供應商可以計算C++程序堆棧所需的最大內存量(如果沒有問題的話):對於遞歸函數,不能計算程序使用的堆棧大小,但對於其他任何情況,堆棧大小都可以通過執行以下操作來計算:
- 使用sizeof(a)用於在堆棧幀
- 總和的每個變量的變量的尺寸,以獲取該堆棧幀
- 列表中的所有可能的堆棧所需的存儲器量幀並計算其大小
- 挑選最大尺寸的調用堆棧
- 選擇該大小作爲程序堆棧的大小。
不幸的是,遞歸函數打破了整個方案。而且它需要全局程序的流程分析來重新識別哪些函數可能具有無限的調用堆棧。但是編譯時sizeof運算符的限制很重要,否則我們的C++程序會隨機用盡堆棧空間,導致崩潰和不穩定。這是不可接受的。因此每個變量和類型都支持編譯時sizeof運算符。
VLA支持要求編譯器可以生成代碼,其中通常生成的偏移量作爲結果機器代碼的常量在運行時實際上是可修改的。符合標準的C++編譯器通常無法做到這一點。 C決定添加這個支持,因此C編譯器可以做到這一點。但在這個過程中,他們需要打破運營商規模。編譯時不再可以計算大小。如在C標準中規定的VLA的支持有很大的問題:
- 你不能把VLA結構或類中
- VLA的基本上僅限於本地函數範圍
這些問題已經解決在C++中通過std :: vector沒有任何這些問題。
來源
2011-04-20 15:59:03
tp1
*但*:沒有C++標準曾接受過C99的VLA,因此從技術上講,在C++中接納VLA的事實是'g ++'擴展。 – 2012-07-28 01:45:31