我正在使用Ubuntu下的g ++ 4.8.4进行编译。
我无法理解为什么下面的代码工作正常意味着打印总是在控制台上输出一些而不会崩溃。
我相信函数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'
...
答案 0 :(得分:3)
行为未定义。
将const
引用绑定到匿名临时文件会将该匿名临时文件的生命周期延长到该const
引用的生命周期。
但是尝试将返回的引用重新绑定到a
中的foo
将不延长生命周期:生命周期扩展不是传递 。因此a
是main()
中的悬空引用。