【问题标题】:Temporary lifetime extension临时延长寿命
【发布时间】:2013-06-28 10:31:19
【问题描述】:

标准的第 12.2.5 节说:

在函数调用中临时绑定到引用参数 (5.2.2) 一直持续到包含 称呼。临时绑定到函数 return 中的返回值 语句 (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 创建一个临时对象并绑定到fooReffooRef#0 线上被销毁。我认为应该在这里销毁临时对象,因为生命周期扩展不是传递的。

问题:

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

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

  3. 如何解释标准引用以了解此示例的工作原理?

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

P。 S. 一个接受的答案here 还告诉代码是broken 我不明白,为什么我会得到这样的程序输出。

【问题讨论】:

  • 当我用 G++ 9.3.0 编译你的代码时,我得到了输出 5。当我使用-O2 标志编译它时,我实际上得到了输出0。添加选项-Wall 会警告使用未初始化的值。相反,使用 clang++ 总是会打印5 并且没有警告消息,与使用的编译器选项无关。但不要依赖这种行为!

标签: c++ reference lifetime object-reference temporary-objects


【解决方案1】:

直到函数退出是什么意思?是指直到执行完毕?

是的。

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

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

如何解释标准引用以了解此示例的工作原理?

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

【讨论】:

    【解决方案2】:
    1. 表示直到右大括号,即}

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

    尝试对您的代码进行以下修改,看看它会打印什么。它可能会打印6,因为这是堆栈中的最后一个。或者尝试传递一个std::string,你可能会遇到崩溃。

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

    【讨论】:

      猜你喜欢
      • 2011-06-07
      • 2011-11-26
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      相关资源
      最近更新 更多