2015-12-22 29 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 –