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

GCC中-fno-elide-constructors选项失效?C++17下拷贝构造未触发

问题解析

你的核心问题出在C++17引入的强制返回值优化(Mandatory Copy Elision),这是标准规定的必做优化,不受-fno-elide-constructors选项控制。

具体原因

在C++17之前,return non_auto{}这种返回临时纯右值(prvalue)的场景,复制/移动构造的省略是编译器的可选优化——你可以用-fno-elide-constructors禁用它,触发拷贝构造调用。

但C++17对这种场景做了根本性修改:标准直接规定,纯右值返回时,编译器必须将临时对象的构造直接定位到目标变量(也就是main里的z)的内存空间中,完全跳过拷贝/移动构造的调用逻辑。这时候哪怕你加上-fno-elide-constructors,也不会改变这个行为——因为这个优化是标准强制要求的,不是编译器的可选优化选项能禁用的。

你的代码里,拷贝构造是私有但没触发编译错误,也侧面证明了这一点:编译器根本没尝试调用拷贝构造,所以不会触及私有成员的访问限制。

如何在C17中重现C14的行为

要让-fno-elide-constructors生效,需要让返回的不是纯右值,而是一个具名对象——这种场景下的返回值优化(NRVO)在C++17中仍然是可选的,编译器可以选择省略,也可以通过选项禁用。

修改foo函数如下:

non_auto foo()
{
  non_auto obj; // 具名局部对象
  return obj;
}

此时用-fno-elide-constructors编译,编译器会尝试调用拷贝构造(但你的代码里拷贝构造是私有,会触发编译错误)。如果把拷贝构造改为public,就能看到"cctor"的输出,和C++14的行为一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 15:29:52