- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对编译器和链接器如何处理函数调用er的要求因函数使用 RVO 或 NRVO 而不同这一事实感到困惑。
这可能是我的误解,但我的假设是一般没有RVO或NRVO
std::string s = get_string();
如果 get_string 不执行 N?RVO,则涉及从 get_string 的结果移动 s 的构造,但如果 get_string 执行 N?RVO,则调用代码不执行任何操作,并且 s
由函数 get_string 就地构造。
编辑:如果没有 N?RVO,这是我想象的 get_string 调用者的操作方式:
现在有了 RVO
最佳答案
无论如何,调用者都会为返回对象分配空间。从调用者的角度来看,函数是否使用 RVO 并不重要。
您还混淆了两个单独的复制省略。有 RVO,它省略了从函数局部变量到返回值的拷贝,还有另一个从函数返回值到被初始化对象的拷贝,也经常被省略。
基本上,在没有任何省略的情况下,您可以认为来自 OP 的调用看起来像这样(忽略任何别名问题,这实际上都将直接在汇编中实现):
void get_string(void* retval)
{
std::string ret;
// do stuff to ret
new(retval) std::string(std::move(ret));
}
char retval[sizeof(std::string)];
get_string(retval);
std::string s(std::move(*(string*)retval));
字符串 ret
被复制(或移动,在本例中)两次:一次从 ret
到 retval
缓冲区,一次从retval
到 s
。
现在,应用 NRVO 后,只有 get_string
的定义会发生变化:
void get_string(void* retval)
{
std::string& ret = *new(retval) std::string;
// do stuff to ret
}
从调用者的角度来看,没有任何改变。该函数只是直接将它要返回的对象初始化到调用者为返回值分配的空间中。现在字符串只移动了一次:从 retval
到 s
。
现在调用者也可以省略一个拷贝,因为不需要分配一个单独的返回值然后将它复制到正在初始化的对象中:
char retval[sizeof(std::string)];
get_string(retval);
std::string& s(*(string*)retval);
这样,s
直接被get_string
初始化,没有进行复制和移动。
关于c++ - C++ ABI如何处理RVO和NRVO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48955310/
考虑以下 C++ >=17 中的示例代码: struct A{ A() = default; A(const A&) = delete; }; const A f(){ return
如何在最后 3 个运算符中强制执行 RVO: #include class Noisy { private: int m_value; public:
我花了一点时间试图了解 RVO 性能影响是否和我想象的一样有值(value)。 这是我的基准代码(主要思想是创建大结构并从函数返回它们): #include #include #include
我不确定我是否应该打扰,因为它不是任何安全关键应用程序,但我只是好奇并且自己无法弄清楚:编译器会为以下方法应用 RVO 吗? QJsonObject MyClass::buildObject(cons
似乎有很多关于编译器何时执行 RVO 或为什么在某某情况下不执行 RVO 的问题。 看完http://cpp-next.com/archive/2009/08/want-speed-pass-by-v
它们是否跨不同的目标文件工作?它们跨不同的 DLL 工作吗? 我知道这取决于编译器。我很好奇是否有任何编译器和优化设置可以使这项工作正常进行。 最佳答案 通常,是的,但原则上,使用链接时间优化(-fl
在过去一天左右的时间里,我一直在学习移动构造函数,试图坚持大多数人似乎建议的按值(value)返回的一般规则,并且遇到了一个有趣的(对我而言)困境。 假设我有一个昂贵的构造/复制类“C”,它具有正确定
这里有很多关于何时可以完成 RVO 的讨论,但关于何时真正完成的讨论并不多。正如多次声明的那样,RVO 不能根据标准得到保证,但是有没有办法保证 RVO 优化成功或相应代码编译失败? 到目前为止,我部
为什么右值优化不会发生在具有通用引用参数的构造函数的类中? http://coliru.stacked-crooked.com/a/672f10c129fe29a0 #include templa
在 AIX 上使用 xlC 编译以下代码会生成打印“2 2”的代码。在带有 gcc 和 clang 的 Linux 上,它可靠地生成“3 3”。 #include struct Numbers {
我有一个表示二进制消息的结构。我想编写一个函数来从缓冲区(无论是文件还是套接字,都无所谓)中获取下一条这样的记录: template Record getNext(); 现在,我可以这样写: tem
http://coliru.stacked-crooked.com/a/c795a5d2bb91ae32 #include struct X { X(const char *) { std:
考虑以下几点: struct A { /* ... */ }; A foo() { auto p = std::make_pair(A{}, 2); // ... do something
在 [C++11: 12.8/31] 中有说明: This elision of copy/move operations, called copy elision, is permitted [..
我有整个故事,关于我发现我从函数返回的无序映射实际上不是 RVO 的令人沮丧的旅程,尽管我确信它在更早的时候是无关紧要的。 有没有办法检查 RVO 是否在任何给定函数中发生?或者像一个做什么和不做什么
在许多情况下,我想创建一个新的数据实例并将其返回给 API 调用方。 我了解到 unique_ptr/shared_ptr 可用于工厂模式(例如, Factory pattern using uniq
假设我写了: Foo get_a_foo() { return reinterpret_cast(get_a_bar()); } 并假设 sizeof(Foo) == sizeof(Bar)。
“返回值优化”的概念是否适用于 C++ 编译器中的 lambda 表达式?我知道这取决于编译器和优化参数,但理论上可能吗? 顺便说一句,有人知道 VS.NET 2013 或更高版本中的这个问题吗? 最
返回值优化机制的简短(可能过时且过于简单)总结如下 this : an implementation may create a hidden object in the caller's stack
我刚刚了解了 RVO(返回值优化)和 NRVO(命名返回值优化)。下面是两个例子 //Example of RVO Bar Foo() { return Bar(); } //Example
我是一名优秀的程序员,十分优秀!