为什么返回引用类型的局部变量在VS2012中有效[重复]

问题描述 投票:0回答:2

我对下面的代码感到非常困惑,该代码在 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 中有效?

在 g++ 8.1.1 中失败

让我睡不着觉。

更新了v1
添加VS2012指定版本并更改代码以使用变量

ri

c++ visual-c++
2个回答
5
投票

这是未定义的行为,这可能会随机工作,因为堆栈帧不会被新值覆盖并且能够访问内存位置(包含垃圾)。我们永远不应该返回对局部变量的引用。


1
投票

我刚刚使用 Visual Studio 2012 Update 4Visual Studio 2013 Update 5Visual Studio 2015 Update 3 和 Visual Studio 2017(15.7 update)尝试了此代码。

在正常警告 (

/W3
) 下,所有四个结果都是:

警告 C4172:返回局部变量或临时变量的地址:i

也许您的警告级别太低了? (

/W0
/W1
)。

至于为什么它起作用,可能是因为您立即将引用转换为值类型,因此您从未真正尝试使用该地址来做任何有趣的事情。正如其他人所指出的,就 C++ 语言而言,这是正式的“未定义行为”。

int ri = func();
© www.soinside.com 2019 - 2024. All rights reserved.