gpt4 book ai didi

c++ - C++ ABI如何处理RVO和NRVO?

转载 作者:太空狗 更新时间:2023-10-29 20:01:57 25 4
gpt4 key购买 nike

我对编译器和链接器如何处理函数调用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 调用者的操作方式:

  1. 调用 get_string()
  2. get_string 结果现在在堆栈上,调用者使用它来构造 s

现在有了 RVO

  1. 调用 get_string()
  2. 当get_string完成后栈上没有结果,get_string构造s,caller不需要做任何事情来构造s。

最佳答案

无论如何,调用者都会为返回对象分配空间。从调用者的角度来看,函数是否使用 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 被复制(或移动,在本例中)两次:一次从 retretval 缓冲区,一次从retvals

现在,应用 NRVO 后,只有 get_string 的定义会发生变化:

void get_string(void* retval)
{
std::string& ret = *new(retval) std::string;
// do stuff to ret
}

从调用者的角度来看,没有任何改变。该函数只是直接将它要返回的对象初始化到调用者为返回值分配的空间中。现在字符串只移动了一次:从 retvals

现在调用者也可以省略一个拷贝,因为不需要分配一个单独的返回值然后将它复制到正在初始化的对象中:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com