强制复制省略? gcc 5.4.1 [英] Mandatory copy elision? gcc 5.4.1

查看:70
本文介绍了强制复制省略? 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆