2015-12-22 28 views
1

我正在使用Ubuntu下的g ++ 4.8.4進行編譯。關於將const引用返回給臨時參數

我不明白爲什麼下面的代碼工作正常意味着總是在控制檯上打印一些輸出而不會崩潰。

我相信功能foo()被分配一個臨時對象,它將持續到功能foo()完成其執行。

當然,輸出參數將指向堆棧中臨時分配的地址,但我很驚訝地發現每個調用A::hello()都能正常工作。

我認爲應該避免訪問該區域的內存。

我想仔細檢查'valgrind',它也表示一切正常。我試圖用-Wstack-protector重新編譯,但沒有任何內容。

你知道它爲什麼會發生嗎?我相信是錯誤的,還是僅僅是那些最能避免的'未定義'C++行爲之一?

#include <iostream>  
using namespace std; 

struct A { 
    A(): a(10) { cout << "a" << endl; } 
    ~A() {cout << "bye" << endl; } 
    void hello() const { cout << "hi " << a << endl; } 
}; 

const A& foo(const A& a = A()) { 
    return a; 
} 

int main() { 
    for(int i = 0; i < 10 ; i++) { 
     const A& a = foo(); 
     a.hello(); 
    } 
    return 0; 
} 


Output 
'a' 
'bye' 
'hi 10' 
'a' 
'bye' 
'hi 10' 
    ... 
+1

未定義的行爲可以做*任何*,包括看起來工作。在這種情況下,該值在打印之前不會被覆蓋。 – BoBTFish

回答

3

行爲是不確定的。

const引用綁定到匿名臨時文件將該匿名臨時文件的生命週期擴展到該const引用的生命週期。

但試圖返回參照afoo重新結合會延長壽命:壽命延長不傳遞。所以a懸掛參考main()

+0

你知道這種行爲是否有名字,以便我可以收集更多信息?儘管如此,我仍然有點困惑。 –

+0

我發現了兩個重要的點,我錯過了http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const和還有一個這裏http://stackoverflow.com/questions/15267676/reference-to-an-unnamed-temporary-object-life-time –