问题标签 [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 投票
4 回答
228 浏览

c++ - 有人可以解释这个 c++ 程序的输出吗?

为什么输出foo3等于3? 我建议,当bar(foo1)被调用时,函数会在堆栈上bar创建一个副本foo1,所以它的值等于 0,当这个值被返回时,复制构造函数foo3再次增加这个值,所以它应该是 2?

提前致谢。

这是我的代码:

输出:

0 投票
0 回答
183 浏览

c++ - 现代 c++ 编译器在什么情况下不执行 rvo?

出于性能原因,我有兴趣确保对函数的返回值执行 RVO。什么会阻止我应该担心的现代 C++ 编译器(例如 gcc、clang 和 msvc 2015)执行这种优化?

澄清编辑:我感兴趣的是识别(希望最终通过某种形式的静态分析,但这可能会在以后出现)何时从函数返回具有昂贵复制构造函数(但便宜的移动构造函数)的特定值,并且不执行 RVO(意味着正在执行不必要的复制构造函数调用)。当 std::move() 调用可以避免这种昂贵的操作时尤其如此。

我特别感兴趣的是编译器实际执行它的情况,而不是 C++ 11 规范允许的情况,我想这比实际实现的情况更广泛。我也对编译器自动使用移动构造函数而不是复制构造函数的情况感兴趣(如果允许的话)。

0 投票
1 回答
511 浏览

c++ - 避免返回的 const locals?

我一直认为让 const locals 成为 const 是件好事

然而,上周我看到一些学生在做 C++ 练习并且想知道返回的 const 指针

在这里,如果编译器不能应用 NRVO(想象在某些情况下这是真的,可能会返回两个指针之一,具体取决于条件),突然const变成悲观,因为编译器不能从 移动p,因为它是 const .

尝试避免const返回的当地人是一个好主意,还是有更好的方法来处理这个问题?

0 投票
0 回答
57 浏览

c++ - nrvo 禁用和复制构造函数

我对编译器的工作方式有点困惑我用 g++ -fno-elide-constructors test.cpp 编译了 prog

f1 的输出没问题,但是在 f2 中,我在赋值运算符之后也得到了复制 const,为什么会这样?

0 投票
1 回答
59 浏览

c++ - 返回对象和 NRVO 的方法的设计模式

我有课:

我想按如下方式使用它:

它工作得很好,没有任何内存泄漏。但是如何在不使用 NRVO 优化的情况下实现类似的行为和用法呢?为此目的存在哪些标准设计模式?

0 投票
2 回答
458 浏览

c++ - RVO 是否适用于这种情况?

假设我们有这种情况

RVO 在这里应用吗?我认为答案是否定的,因为应用 RVO 的规则之一是:“如果函数按值返回类类型,并且 return 语句的表达式是具有自动存储持续时间的非易失性对象的名称,则t 函数参数,或 catch 子句参数,并且与函数的返回类型具有相同的类型(忽略顶级 cv 限定),则省略复制/移动“并且在这种情况下,返回的对象不具有与函数的返回类型相同的类型,但我不是 100% 不在这里应用 RVO。

非常感谢。

PS。在本次演讲中https://www.youtube.com/watch?v=AKtHxKJRwp4(第 40 分钟,第 18 秒)来自 Microsoft 的 Stephan 谈到了无法应用 RVO 的情况,因为函数的返回类型不同于返回对象的类型(在他的示例中为元组与对)。我认为同样的原则也适用于此。

0 投票
0 回答
117 浏览

c++ - (N)RVO 是否适用于大小相同的子对象(成员或基础)?

使用 RVO,我们可以从函数返回局部变量,而不会产生复制成本。这在返回变量的子对象时也有效吗?

从其他答案中,我收集到当完整对象的大小大于要返回的对象时,它不会,因为它不适合为返回值保留的空间。但是如果整个对象是“空的”,即大小与子对象相同,那又如何呢?


我问这个问题的理由:

假设我有一个简单的对象

和一个包装类,它只是作为数据的更智能视图:

这被一些返回Data以简化实现的函数在内部使用,但接口没有反映这一点(即函数不返回包装器本身)。所以我可能有一个功能:

由于这个用例对于我的包装器来说很常见,我想用一个封装它的类来替换它。makeTheData即,我将用包含Data子对象和包装器功能的单个本地对象替换前两行。

这将有助于实现包装器的常见用例。该ContainingWrapper对象与对象具有相同的大小Data,因此 RVO 在技术上应该是可行的。

能否在不损失 RVO 性能(至关重要)的情况下实现此功能(使用成员或基础子对象,或者可能使用不同的方法)?as if规则是否适用并允许优化器将第二个实现makeTheData转换为第一个实现,从而使 RVO 成为可能?

0 投票
1 回答
391 浏览

c++ - 为什么没有复制构造函数 NRVO 不能工作

我正在阅读Inside C++ Object Model一书,我得到了以下内容:
在此处输入图像描述

据我所知,NRVO不会调用函数返回的类的复制构造函数。所以我不明白为什么“由于缺少复制构造函数,该程序的第一个版本不应用NRV优化...... ”。

0 投票
1 回答
455 浏览

c++ - C++ RVO:什么时候发生?

http://coliru.stacked-crooked.com/a/c795a5d2bb91ae32

函数的最后一行有什么区别f(X a): return a;而不是return std::move(a);?

功能f没有RVO但g有NRVO是真的吗?

0 投票
2 回答
430 浏览

c++ - c++ - NRVO 和移动

我已经阅读了一些关于移动函数的帖子(例如http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html),我想要观察移动操作员的动作。所以我尝试了以下代码:

我期待为局部变量获得相同的地址,result因为c移动运算符是为vector. 我得到了确切的结果,但是有和没有 flag -std=c++11。那是我了解 NRVO(c++11 返回值优化还是移动?)的时候,所以我用标志禁用了它,-fno-elide-constructors现在地址不同了,即使有标志也是如此-std=c++11。我的代码有问题还是我对移动运算符有什么误解?

据我了解,按值返回应该足以让移动运算符发挥作用(C++11 右值和移动语义混淆(返回语句))。

PS:我尝试使用 GCC 6.3.0_1 和 Apple LLVM 版本 8.1.0 。

编辑

正如所指出的,我应该检查result.data()而不是&result(见下文)。但在那种情况下,我总是找到相同的地址,即使没有std=c++11和有-fno-elide-constructors. 请参阅接受的答案及其评论部分。