返回对局部变量的引用

7

可能是重复问题:
返回本地或临时变量的地址
在其范围之外访问局部变量的内存是否可行?

即使知道以下代码片段的结果,了解它是如何发生的也会很有帮助。接下来有四个问题。

给定:

int& foo()
{
    int i = 1;
    return i;
}

了解以下内容:对名为 i 的本地变量的引用被取消引用,转换为一个临时变量,该临时变量被分配给intVal,在foo()结束时,本地变量 i 消失。

int  intVal = foo();

第一个问题 - 在下面的表达式中,右侧与上方相同,因此编译器是否看到左侧,并根据上下文知道不要对返回的引用取消引用,而是创建一个新的引用并将其初始化?

第二个问题 - 仅这个条件就使得本地变量 i 在 intRef 作用域内存在吗?

int& intRef = foo();

第三个问题 - 下面的 intPtr 获取了 本地 i 的地址。那么,编译器是否使用赋值的上下文,并决定在获取引用的地址之前不对其进行解引用以获取值(而不是说获取包含已解引用值的临时变量的地址)?

第四个问题 - 当 intPtr 在作用域内时,本地 i 是否仍然存在?

int* intPtr = &foo();   

2
知道这里发生了什么毫无意义。顺便说一下,它从来不会停留,而且在第一个中,它没有停留足够长的时间发生任何事情。 - R. Martinho Fernandes
因为完全重复而关闭? 我的主要关注点是问题1和3,它们涉及LHS上下文确定如何处理RHS(是否取消引用)。 甚至“完全重复”都没有触及此问题。 - Arbalest
2个回答

6

不行,这些都不能延长本地变量的生存期。在C++中,没有任何东西能够产生这种效果。C++中的局部对象的生命周期仅限于它们声明的作用域的结束。

唯一一个规则,乍一看似乎有不同规则的是:

int foo() {
    return 42;
}

int main() {
    const int& i = foo();
    // here, `i` is a reference to the temporary that was returned from `foo`, and whose lifetime has been extended
}

也就是说,一个const引用可以延长被赋值给它的临时对象的生命周期。

但这需要函数返回一个值,而不是引用,并且调用者将返回值绑定到一个const引用上,而你的代码都没有做到。


要求该函数返回一个值,而不是一个引用。 - Mihai Todor

0
在任何情况下(不是intVal,也不是intRef,也不是intPtr),i在foo返回后不一定会保留。
之前被i占用的堆栈上的值可能会随时更改,在foo返回后可能会更改。
例如(在某些CPU和操作系统上),它很可能会被任何后续调用子例程的更改所更改,并且如果硬件中断发生,则可能会更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接