2010-09-01 171 views
1

我不明白爲什麼代碼在VS2010中打印'3'(發佈版本),無論我是否留下'r'聲明或將其註釋掉。混淆輸出?

int main(){ 
    int arr1[2]; 
    int &r = arr1[0]; 
    int arr2[2]; 

    cout << (&arr1[1] - &arr2[0]); 
} 

所以,三個問題:

一個。爲什麼代碼打印3?

b。爲什麼即使存在'r'聲明也打印3? (是否因爲在C++中引用佔用存儲與否是實現定義的?)

c。此代碼是否具有未定義的行爲或實現定義的行爲?

回答

0

&arr1[1] - &arr2[0]

指針運算僅在同一陣列中明確定義。無論您認爲此代碼片段做了什麼或應該做什麼,都會調用未定義的行爲。你的程序可以做什麼

3

因爲在Release build r變量被刪除。內置類型的未使用變量被刪除,因爲發佈版本是通過優化完成的。嘗試稍後使用它,結果將會改變。有些變量可能放入CPU寄存器而不放在堆棧上,這也會改變另一個局部變量之間的距離。

另一方面,未使用的類實例未被刪除,因爲類實例創建可能有副作用,因爲調用構造函數。

這是未定義的和實現定義的行爲,因爲編譯器可以自由地將變量放在適當的地方。

2

a。內存中變量的順序是從

arr2[0] 
arr2[1] 
arr1[0] 
arr1[1] 

代碼打印3因爲它使用指針算術。減去& arr1 [1] from & arr2 [0]表示3個int的差值。

b。由於r從未被引用,因此C++編譯器可以自由優化它。

c。不是肯定的,但我不相信C++標準定義了棧上變量的顯式順序。因此,編譯器可以自由地對這些變量進行重新排序,甚至在它們看起來合適時在它們之間留出額外空間。所以,是它的具體實現。不同的編譯器可以像答案一樣容易地給出-1。