這是否總是按預期運行?可變尺寸陣列的範圍
char *x;
if (...) {
int len = dynamic_function();
char x2[len];
sprintf(x2, "hello %s", ...);
x = x2;
}
printf("%s\n", x);
// prints hello
編譯器如何(在我的情況GCC)實現可變大小的數組,每個C和C++的?
這是否總是按預期運行?可變尺寸陣列的範圍
char *x;
if (...) {
int len = dynamic_function();
char x2[len];
sprintf(x2, "hello %s", ...);
x = x2;
}
printf("%s\n", x);
// prints hello
編譯器如何(在我的情況GCC)實現可變大小的數組,每個C和C++的?
編號x2
位於if
語句的作用域的本地,您可以使用指針在其外部訪問它。這導致未定義的行爲。
順便說一下,在C11中,VLA已經成爲可選項,並且從未成爲C++的一部分。所以最好避免它。
另一方面,VLA的(非常)受限形式正在悄悄進入下一個C++標準;-) –
VLA僅在C99中添加,甚至在C99變得普遍之前,它有點尷尬,他們刪除了它從標準! –
否,對於兩個單獨的原因:
C++:該代碼是無效的C++。 C++中的數組必須具有編譯時常量大小。
C:不,因爲該數組只能存在,直到它聲明的塊的末尾,因此解引用x
是未定義的行爲。
從C11,6.2.4/2:
如果對象被稱爲它的壽命之外,則該行爲是未定義的。
而且6.2.4/7說,可變長度數組從聲明住直到其封閉範圍的末尾:
對於這樣一個對象,該對象不具有可變長度數組類型,其生命週期從 延伸到對象的聲明,直到程序執行離開 聲明的範圍。
取決於語言。這是C++中的一個編譯器擴展。 – chris
它沒有。由於您聲明瞭一個變量char x2 [],因此它會從堆/進程虛擬內存中詢問空間並始終保持相同。 當你寫x = x2時,你將x指向與x2相同的內存空間,因爲x是一個指針,但它不會總是一樣,printf x沒有初始化就會打印垃圾。 –
根據我的理解,x2在if語句後不復存在,因此無法知道打印輸出是什麼 – Smash