17

该标准的第 12.2.5 节说:

临时绑定到函数调用 (5.2.2) 中的引用参数将一直持续到包含调用的完整表达式完成为止。在函数返回语句 (6.6.3) 中对返回值的临时绑定将持续存在,直到函数退出。在所有这些情况下,在初始化引用的表达式的求值过程中创建的临时对象,除了引用绑定的临时对象,在创建它们的完整表达式的末尾被销毁,并且与完成他们的建设。

我试图理解以下代码:

#include <iostream>

const int& foo(const int& fooRef)
{
    return fooRef;
}                                        // #0

int main (void)
{
    const int& numberRef = foo(5);     // #1
    std::cout << numberRef;            // #2
    return 0;
}

在线#1创建一个临时对象并将其绑定到fooRef. fooRef在线销毁#0。我认为应该在这里销毁临时文件,因为生命周期扩展不是传递的。

问题:

  1. 是什么until the function exits意思?这是什么意思untill it finished executing

  2. 为什么我得到一个5输出。临时对象是否仍然存在在线#2

  3. 我如何解释标准报价以了解此示例的工作原理?

非常感谢参考标准的逐步原子演练。谢谢!

PS这里接受的答案还告诉代码是broken我不明白,为什么我会得到这样的程序输出。

4

2 回答 2

10

直到函数退出是什么意思?这是否意味着直到它完成执行?

是的。

为什么我得到一个 5 输出。第 2 行是否仍然存在临时对象?

取消引用未绑定到活动对象的引用是未定义的行为,因此您可能会得到和其他任何东西5一样42好(包括崩溃)。您根本不能对具有未定义行为的程序抱有任何期望。

我如何解释标准报价以了解此示例的工作原理?

就像你已经做的一样。临时绑定到函数参数fooRef,从函数返回时被销毁。由于该临时对象绑定到返回值,因此该对象在函数返回时不再存在。稍后,您将取消引用一个悬空引用,从而为您提供 UB。

于 2013-06-28T10:36:46.823 回答
2
  1. 这意味着直到右大括号,即}.

  2. 你调用了 UB,你有一个悬空的引用。

尝试对您的代码进行以下修改,看看它会打印什么。它可能会打印6,因为那是堆栈上的最后一个。或者尝试通过 astd::string代替,您可能会崩溃。

int main (void)
{
    const int& numberRef = foo(5);  
    foo(6);
    std::cout << numberRef;
    return 0;
}
于 2013-06-28T10:40:26.310 回答