c++ - 强制复制省略?海湾合作委员会 5.4.1

标签 c++ c++11 gcc

我目前正在努力使用 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/

相关文章:

c++ - Qt 文件调整大小在 Linux 中表现怪异

c++ - 静态初始化具有可变长度数组的结构

c++ - 编译时函数求值,不完整类型

c++ - 警告 : 'auto' type specifier is a C++11 extension

c++ - 有没有办法在c++03中模拟c++11 'override'说明符的效果?

c++ - 如果 T 不是整数,如何禁用非空 std::set 作为函数参数?

c++ - 不同编译器的打包结构大小和继承

c++ - extern const 字符串的链接错误

c - 为什么我们可以通过在 C 代码中重新分配变量来永久避免寄存器溢出?

c++ - 内联关键字与标题定义