我对下面的代码感到非常困惑,该代码在 VS2012 Update 5 中有效,但在 g++ 8.1 中失败。
int& func()
{
int i = 0;
return i;
}
int main()
{
int ri = func();
ri++;
std::cout << ri << std::endl; // output "1"
return 0;
}
根据我的理解并参考类似的问题C++ Returning引用局部变量,它应该失败,因为函数
i
中局部变量func
的生命周期应该在函数调用后结束。
但是,为什么它在 VS2012 中有效?
让我睡不着觉。
更新了v1:
添加VS2012指定版本并更改代码以使用变量
ri
。
这是未定义的行为,这可能会随机工作,因为堆栈帧不会被新值覆盖并且能够访问内存位置(包含垃圾)。我们永远不应该返回对局部变量的引用。
我刚刚使用 Visual Studio 2012 Update 4、Visual Studio 2013 Update 5、Visual Studio 2015 Update 3 和 Visual Studio 2017(15.7 update)尝试了此代码。
在正常警告 (
/W3
) 下,所有四个结果都是:
警告 C4172:返回局部变量或临时变量的地址:i
也许您的警告级别太低了? (
/W0
或 /W1
)。
至于为什么它起作用,可能是因为您立即将引用转换为值类型,因此您从未真正尝试使用该地址来做任何有趣的事情。正如其他人所指出的,就 C++ 语言而言,这是正式的“未定义行为”。
int ri = func();