问题标签 [nrvo]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
161 浏览

c++ - 哪些因素决定是否使用 (N)VRO?

(受这个问题的启发,不幸的是这是主观的)。

哪些因素会影响编译器是否选择应用 (N)VRO?

我知道有两大类因素,因为优化器需要回答关于 (N)VRO 决策的两个问题:(1)它甚至可能吗?(2)它是一种优化吗?我希望每个因素都只适用于这两个问题中的一个。

请不要对优化部分进行毫无根据的猜测。当您可以准确解释它如何影响优化时,可以列出一个因素,或者一个现有编译器使用的因素。但不要在sizeof(T)不解释这如何影响申请 (N)VRO 的决定的情况下说。

0 投票
0 回答
159 浏览

c++ - 无法按值从数组中返回 unique_ptr 元素

以下编译并按预期工作:

但这不会:

g++ 输出:error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = char; _Dp = std::default_delete<char>]

从一些 SO 研究中返回 unique_ptr from functions为什么我不能从一对中返回 unique_ptr?似乎这都与复制省略命名返回值优化有关。

有人可以确认我的猜测是否正确。如果是这样,复制 elison的确切标准是什么,以便可以应用 NRVO ?

0 投票
2 回答
285 浏览

c++ - RVO 是否与“新”一起使用?

在这种情况下会出现复制省略吗?换句话说,具有复制省略的现代编译器是否避免在这里调用任何复制构造函数?

我的目标是将对象存储在指针中。对象由函数返回。我想存储它而不复制它。

我不能使用 c++11

0 投票
1 回答
56 浏览

c++ - 当值被复制到现有对象时,(N)RVO 是否也会发生?

(N)RVO 有助于在将返回值分配给新变量时避免不必要的复制和创建临时对象(从而避免复制构造函数)。

所以像这样的事情应该由 RVO 优化:

但是,调用站点对象已经存在时也会发生这种情况吗?(即在使用=运算符而不是复制构造函数的情况下)。我试图找到有关此的文献,但 (N)RVO 似乎总是被描述为避免使用复制构造函数。不确定在这种情况下修改调用站点对象是否真的安全。

0 投票
1 回答
1407 浏览

c++ - 禁用一个函数的返回值优化

  • foo() 在汇编器中实现 (i386)
  • X 类型的返回值的地址作为隐藏参数传递给 foo()

  • 如果使用 -O0 编译测试代码,则代码按预期工作

  • 如果使用 -O3 编译发生分段错误(返回值已优化)
  • 如果使用 -O3 -fno-elide-constructors 编译,代码将再次按预期工作

如何强制编译器不只为 foo() 添加 RVO(也就是不强制 -fno-elide-constructors)?

Update1:​​代码必须适用于任意编译器(至少 gcc、clang、msvc),示例代码:

Update2:问题是,编译器优化了 x 的实例

或者

没关系。例如,发生段错误是因为

x1 被优化,实现尝试访问第一个参数,它是一个空指针。

0 投票
0 回答
565 浏览

c++ - RVO 和 std::vector 实现

我编写了下面的代码来检查流行的 C++03 编译器是否尽可能实现 RVO。(请参阅我关于 RVO返回值优化的相关问题:我可以避免复制构建巨大的 STL 容器。)。

据我了解,简短的回答是否定的。但我不确定我是否理解。

关于 clang gcc 和 VS9 的 std::vector 实现,我有以下五个问题,请阅读下面的代码和输出:

  1. 为什么编译器 C Fun1 将向量复制两次?
  2. 为什么编译器 B 和 C 总是构造至少一个非请求元素?
  3. 为什么这个非请求元素用编译器 C Fun2 生成两次?
  4. 为什么保留空间会为编译器 B 和 C 产生一个非请求元素?
  5. 所有这些标准都符合吗?
  6. 奖励问题:这一切是否符合用户的期望?

使用流行的 C++11 编译器 A 输出

使用流行的 C++03 编译器 B 输出

使用流行的 C++03 编译器 C 输出

0 投票
1 回答
124 浏览

c++ - 关于复制构造函数和 NRVO

即使第 2 行没有将临时对象作为参数,如果我不在复制构造函数参数中添加 const,我仍然会收到编译器错误。在第 3 行的情况下,重载的运算符使用 NRVO 返回一个对象。因此它不应该使用复制构造函数。但它仍然给出编译器错误。如果我在复制构造函数参数中添加一个 const,这两个错误都会消失。但是为什么它会给出错误呢?

0 投票
1 回答
253 浏览

c - 在 gcc 中为纯 C 禁用命名返回值优化

我找不到控制 C 语言的命名返回值优化的标志。对于 C++,它似乎是 -fno-elide-constructors。

实现它的源代码在这里,但由于它是一个中间端,即使在注释中也不会破坏前端信息。 手册部分也没有完全帮助。但是反汇编显示,由于它在 O0 上关闭并在 O1 上启用,因此它必须是以下之一:

C代码:

使用 O0 编译,我们看到“复制”结构天真地分配在堆栈上:

用 O1 编译它没有分配,但指针作为隐式参数传递

0 投票
2 回答
515 浏览

c++ - 带返回的编译器优化 (std::stringstream ss).str()

以下函数接受一个字符串作为参数,并在经过一些处理后返回另一个。

  1. 假设编译器将执行移动优化是否足够公平,并且我不会在每次调用后复制字符串的内容?这个函数应该遵循复制省略 [(N)RVO] 吗?

  2. 作为一种做法,这是可取的吗?

因为,否则,我一般遵循通过引用返回字符串的做法。所以,可以说,我的函数签名是:

0 投票
1 回答
143 浏览

c++ - 引入新变量是否会破坏返回值优化?

我们都知道

Foo将使用返回值优化进行编译,因此即使 的复制构造函数有副作用,也不会进行值复制。但是会

也?第二个构造在调试时会很有帮助。但是我这样做是不是丢掉了一个重要的优化?也许我需要编写一个显式的移动构造函数?