我目前正在努力使用 C++ 和 copy elision ,特别是“命名返回值优化”(NRVO),以便能够实现工厂功能模式。我无法在不同的编译器中获得一致的行为。我的妈妈:
#include <iostream>
struct base {
virtual ~base() { std::cout << "dtor base\n"; }
};
struct derived : public base {
~derived() { std::cout << "dtor derived\n"; }
};
derived f() { return derived(); }
int main(int argc, char *argv[]) {
std::cout << "start\n";
new derived(f());
std::cout << "done. should have leaked!\n";
}
注意:删除 virtual base-dtor 可以解决问题,但我的实际实现需要它。
在 gcc 5.4.0 的情况下,调用 dtor,不执行复制省略:
$ g++ test2.cpp && ./a.out
start
dtor derived
dtor base
done. should have leaked!
当使用 gcc 5.4.1(Ubuntu 称之为 5.4.1,我假设这是 svn-head)时,我能得到的所有 clang 以及其他各种 gcc 执行省略并成功泄漏内存:
$ g++ test2.cpp && ./a.out
start
done. should have leaked!
当我在 internetz 上阅读不同的地方时,允许编译器进行复制省略,但不是必需的。只有 c++17 引入了保证复制 elision .那么这是 gcc 5.4.0 中的错误,还是只是以不同方式实现了标准?
最佳答案
在 C++17 之前,复制省略是一个可选的优化,即使在 C++17 中,它也只是在某些情况下是强制性的。据我所知,即使在 C++17 中,(N)RVO 复制省略也不是强制性的——唯一强制性的复制省略情况是使用临时初始化。
(N)RVO 不应该改变你的程序的行为,也不应该是你的程序正常运行所必需的。您应该以这样一种方式编写您的代码,无论 (N)RVO 如何,它都能正常工作,并且当/如果 (N)RVO 启动时,它可以更快地工作。
关于c++ - 强制复制省略?海湾合作委员会 5.4.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41466847/