You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用-fno-elide-constructors时,C++11传值函数临时对象销毁时机疑问

C++11中函数按值传参的临时对象销毁时机问题

我把代码从C17改成C11后,遇到了关于临时对象销毁时机的困惑,以下是相关代码、编译命令和输出结果:

代码示例

#include <cstdio>
#include <iostream>
#include <initializer_list>
using namespace std;
class A {
public:
    static int s;
    int t = s;
    A(){ cout << "constructed" << t<< endl; s++; }
    A (A&& a) { cout << "in move ctor, moving"<< a.t << " creating" << s << endl; s++; }
    ~A() { cout << "deleting"<< t << endl; }
};
A f1 (A a) {
    std::cout << "f1: " << endl;
    return a;
}
int A::s = 0;
int main() {
    f1(A()) ;
    std::cout << "is still alive!" << endl;
}

编译命令

g++ -std=c++11 -fno-elide-constructors -Wall -pedantic -pthread main.cpp && ./a.out

输出结果

constructed0
in move ctor, moving0 creating1
f1:
in move ctor, moving1 creating2
deleting2
deleting1
deleting0
is still alive!

我的疑问

我无法理解该结果:若f1按值接收A类型参数,传入的是A&&临时对象,那么f1内部应创建临时对象"a"(对应输出中的1),按预期该对象应在f1退出时销毁,但实际它和其他临时对象一起在该行代码结束时销毁。请问:专为函数创建的对象是在函数结束时销毁,还是在创建它的代码行结束时销毁?


解答

咱们结合C++11的标准规则一步步拆解这个问题:

  1. 先理清对象的创建链

    • 调用f1(A())时,首先会生成第一个临时对象temp0(对应输出的constructed0);
    • 因为f1是按值传参,所以会用temp0移动构造出函数的形参a(也就是输出里的in move ctor, moving0 creating1,这个a的t值是1);
    • 你禁用了返回值优化(-fno-elide-constructors),所以函数返回a时,又会从a移动构造出返回值临时对象ret_temp(对应in move ctor, moving1 creating2,这个对象的t值是2)。
  2. 为什么形参a没在函数结束时销毁?

    • 正常情况下,函数形参确实会在函数执行完毕后立即销毁,但C++11有个特殊规则:当函数返回的是自动存储期的对象(比如这里的形参a),并且该对象被用来初始化函数调用的返回值临时对象时,形参的生命周期会被延长到整个函数调用表达式结束时。
    • 简单说,f1(A())这一整行是一个完整表达式,它产生的返回值临时对象ret_temp会在这行代码执行完毕后才销毁。而形参a、最初的临时对象temp0的销毁时机被绑定到了ret_temp上,所以三者会在同一时刻被销毁,这就是你看到三个deleting输出都在is still alive!之前的原因。
  3. 如果开启返回值优化会怎样?

    • 要是去掉-fno-elide-constructors,C++11允许编译器直接省略中间的两次移动构造:直接把最初的temp0当作形参a使用,再直接作为返回值返回,这样整个流程只会有一次构造和一次销毁,就不会出现多个对象延迟销毁的情况了。

总结一下:

  • 普通场景下,函数形参会在函数执行完毕后立即销毁;
  • 但当形参被用来初始化函数返回值临时对象时(尤其是禁用返回值优化的场景),它的生命周期会被延长到整个函数调用表达式结束,和其他相关临时对象一起销毁。

内容的提问来源于stack exchange,提问作者DsCpp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:52:51