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

C++17/20编译器对返回局部变量的优化:复制消除还是移动构造?

C17/C20中返回局部对象的优化问题

我们先明确给定的类定义:

class Foo {
public:
  Foo() = default;
  Foo(const Foo&) = default;
  Foo(Foo&&) = default;
  // other functions...
private:
  // a bunch of data members...
};

以及待分析的函数:

Foo CreateFoo() {
  Foo foo;
  // Do more things with foo ...
  return foo;  // 此处是否使用了copy elision?若未使用,是否会被优化为return std::move(foo)?
}

1. 复制消除(Copy Elision)的情况

在C++17及以后的标准中,这种场景下的复制消除是强制要求的,编译器必须执行返回值优化(RVO),不会调用拷贝构造函数或移动构造函数,而是直接在函数调用的目标内存位置构造foo对象。

具体来说,C++17规定:当函数返回的是一个具有自动存储期的非volatile对象,且该对象的类型与函数返回类型完全匹配时,编译器必须省略拷贝/移动操作,直接将局部对象构造到函数返回的目标区域中。

2. 若复制消除未执行(仅理论极端场景)

如果出于某些特殊情况(比如编译器刻意关闭优化、代码存在阻止优化的特殊操作,但符合标准的编译器几乎不会出现这种情况)复制消除未发生,那么编译器会自动将return foo处理为return std::move(foo),也就是调用移动构造函数而非拷贝构造函数。这是因为C++标准规定,当返回的局部对象是返回语句的操作数时,编译器会将其视为右值,优先触发移动构造。

需要注意的是,这种自动移动的行为在C11及以后就已存在,而C17将RVO从可选优化升级为强制要求,所以在合规的C17/C20编译器中,你几乎只会看到复制消除的结果,不会触发移动构造。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:02:12