关于返回对临时参数的 const 引用
about returning a const reference to a temporary argument
我正在 Ubuntu 下使用 g++ 4.8.4 进行编译。
我不明白为什么下面的代码可以正常工作意味着总是在控制台上打印一些输出而不会崩溃。
我相信函数 foo()
被分配了一个临时对象,该对象将持续到函数 foo()
完成执行。
输出参数肯定会指向分配临时变量的堆栈上的相同地址,但我惊讶地发现每次调用 A::hello()
都可以正常工作。
我认为应该避免对该内存区域的任何访问。
我想用 'valgrind' 仔细检查,它也说一切正常。我尝试用 -Wstack-protector
重新编译,但没有。
你知道为什么会这样吗?我的看法是错误的,还是这只是最好避免的 'undefined' 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'
...
行为未定义。
将 const
引用绑定到匿名临时文件会将匿名临时文件的生命周期延长到 const
引用的生命周期。
但是在 foo
中尝试重新绑定对 a
的返回引用将 不会 延长生命周期:生命周期延长不是 传递。所以 a
是 悬空 引用 main()
.
我正在 Ubuntu 下使用 g++ 4.8.4 进行编译。
我不明白为什么下面的代码可以正常工作意味着总是在控制台上打印一些输出而不会崩溃。
我相信函数 foo()
被分配了一个临时对象,该对象将持续到函数 foo()
完成执行。
输出参数肯定会指向分配临时变量的堆栈上的相同地址,但我惊讶地发现每次调用 A::hello()
都可以正常工作。
我认为应该避免对该内存区域的任何访问。
我想用 'valgrind' 仔细检查,它也说一切正常。我尝试用 -Wstack-protector
重新编译,但没有。
你知道为什么会这样吗?我的看法是错误的,还是这只是最好避免的 'undefined' 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'
...
行为未定义。
将 const
引用绑定到匿名临时文件会将匿名临时文件的生命周期延长到 const
引用的生命周期。
但是在 foo
中尝试重新绑定对 a
的返回引用将 不会 延长生命周期:生命周期延长不是 传递。所以 a
是 悬空 引用 main()
.