强制复制省略? gcc 5.4.1 [英] Mandatory copy elision? gcc 5.4.1
问题描述
我目前正在努力使用c ++和复制省略,特别是名为返回值优化(NRVO),以便能够实现工厂功能模式。我无法在不同的编译器之间获得一致的行为。我的mwe:
I'm currently struggling with c++ and copy elision, specifically "named return value optimization" (NRVO), to be able to implement a factory-function pattern. I cannot obtain consistent behavior across different compilers. My mwe:
#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";
}
注意:删除虚拟base-dtor可以解决问题,但我需要我的真正实现。
Note: Removing virtual base-dtor solves the problem, but I need it for my real implementation.
在gcc 5.4.0中,调用dtor时,不会执行复制省略:
In case of gcc 5.4.0 the dtor is called, no copy elision is performed:
$ g++ test2.cpp && ./a.out
start
dtor derived
dtor base
done. should have leaked!
在使用gcc 5.4.1时(Ubuntu称之为5.4.1,我认为这是svn-head ),所有我能接触到的c声以及其他各种gcc都会执行省略操作并成功泄漏内存:
When using gcc 5.4.1 (Ubuntu calls it 5.4.1, I assume this is svn-head), all clangs I could get my hand on as well as various other gccs perform elision and successfully leak the memory:
$ g++ test2.cpp && ./a.out
start
done. should have leaked!
当我阅读internetz上的不同地方时,允许编译器 进行复制省略,但不是必需的。只有c ++ 17引入保证副本 elision 。那么,这是gcc 5.4.0中的bug,还是只是以不同的方式实现了标准?
As I read the different places across the internetz, the compiler is allowed to do copy elision but not required. Only c++17 introduces guaranteed copy elision. So is this a bug in gcc 5.4.0, or is it just implementing the standard differently?
推荐答案
复制省略是可选的直到C ++ 17才进行优化,甚至在C ++ 17中也只有在某些情况下才必须进行优化。据我所知,即使在C ++ 17中,(N)RVO复制删除也不是强制性的-唯一的强制复制删除情况是使用临时初始化。
Copy elision is an optional optimization until C++17, and even in C++17 it is only mandatory in certain cases. As far as I remember, (N)RVO copy elision is not mandatory even in C++17 — the only mandatory copy-elision case is an initialization with temporary.
(N)RVO绝不能改变程序的行为,也绝不能要求程序正常运行。您应该以这样一种方式编写代码,使其无论(N)RVO为何都可以正常工作,并且只要/ N(R)RVO插入时便可以更快地工作。
(N)RVO should never alter your program's behaviour and should never be required for your program to function properly. You should write your code in such a way that it works properly regardless of (N)RVO, and simply works faster when/if (N)RVO kicks in.
这篇关于强制复制省略? gcc 5.4.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!