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
相关产品推荐
相关产品推荐

