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

2024-01-04

我对编译器和链接器如何处理调用要求这一事实感到困惑er该功能的不同取决于该功能是否使用 RVO 还是 NRVO。

这可能是我的误解,但我的假设是通常没有 RVO 或 NRVO

std::string s = get_string();

如果 get_string 不执行 N?RVO 但如果 get_string 执行 N?RVO 调用代码不执行任何操作,则涉及从 get_string 的结果移动 s 的构造s由函数 get_string 就地构造。

编辑: 如果没有 N?RVO,我想象 get_string 调用者的操作方式如下:

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

现在有了 RVO

  1. 调用 get_string()
  2. 当 get_string 完成时,堆栈上没有结果,get_string 构造了 s,调用者不需要执行任何操作来构造 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被复制(或移动,在本例中)两次:一次来自ret to the retval缓冲区,并且一旦来自retval to s.

现在,应用 NRVO 后,只需定义get_string会改变:

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

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

现在调用者还可以删除副本,因为不需要分配单独的返回值,然后将其复制到正在初始化的对象中:

char retval[sizeof(std::string)];
get_string(retval);
std::string& s(*(string*)retval);

这样,s直接初始化为get_string,并且不执行任何复制或移动。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ ABI 如何处理 RVO 和 NRVO? 的相关文章

  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐

  • Magento CMS 错误:前端控制器达到 100 次路由器匹配迭代

    当我通过 CMS 在管理中 创建页面时 一切看起来都很好 但是当我尝试访问前端中的页面时 我得到一个带有错误的空白页面 Front controller reached 100 router match iterations 0 app c
  • NoSQL 的用例[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 NoSQL 最近在我们行业受到了广泛的关注 我真的很感兴趣人们对它在关系数据库存储上的最佳用例的看法 什么会促使开发人员认为特定数据集更适合 N
  • 在 Git 中的根提交之前插入非空提交?

    我有一个问题 请各位好心人指教 我有一个现有的 git 存储库 并且由于各种原因 我不会在这里讨论 我正在尝试创建一个 ROOT 提交 假设这是我的 git 提交历史记录 ROOT C1 lt C2 lt C3 lt C4 lt C5 lt
  • jQuery:如何制作一个清晰的按钮?

    我有一个搜索字段 我需要一个清晰的按钮 我目前有按钮 但我不知道该怎么做 我有 6 个文本字段 2 个组合框和 2 个多选列表 如何在一个清除函数中清除所有这些 我知道 HTML 方式 但我使用 Grails 并且 type reset 不
  • 如何使用 Chart.js 更改 Barchart 中仅一列的颜色

    js http www chartjs org docs bar chart http www chartjs org docs bar chart 我正在使用基本示例 HTML
  • 是否可以在单手柄 jQuery UI 滑块上设置固定的静态范围?

    本质上我要做的是一个用于一堆日期的单句柄 jQuery UI 滑块 选择的日期范围始终为两周 我想做的只是显示从两周范围的开始日期 即句柄驻留的日期 开始的一个范围 该范围不必是功能性的 只是显示 向前两周 这个范围是固定的 例如 如果句柄
  • 从 Eclipse 远程部署 Tomcat Web 应用程序

    出于开发和测试目的 我想将我的 web 应用程序从 eclipse 部署到远程 tomcat 服务器 这可能吗 如果没有 我应该如何设置我的开发环境以实现顺利 轻松的远程部署 如果您可以远程访问 Tomcat 管理器应用程序 那么您可以使用
  • 让用户选择他希望程序使用多少个线程

    我想让一个程序读取 txt 文件的每一行 并对每一行执行一些操作 我希望用户能够选择线程 因此如果他选择 10 个线程 那么程序将能够同时在 10 行上执行某些操作 假设文本文件包含 1 000 000 行 我该怎么办 这就是我实际上所拥有
  • 如何确定 connectNative 是失败还是成功

    我已成功将我的扩展连接到我们的本机主机 var pulse tracker port chrome runtime connectNative com cloudfactory pulsetracker 但我如何知道连接是否成功呢 无论连接
  • Xcode 5“缺少编译器规范 LLVM 4.2”错误

    我目前正在尝试在 Xcode 5 中构建我的项目 构建失败并出现错误 依赖性分析错误 missing compiler specification
  • 抽象工厂设计模式

    我正在为我的公司开发一个内部项目 该项目的一部分是能够将 XML 文件中的各种 任务 解析为稍后运行的任务集合 由于每种类型的任务都有许多不同的关联字段 因此我决定最好用单独的类来表示每种类型的任务 为此 我构造了一个抽象基类 public
  • 输入上的 v-model 通过其他脚本动态更改值?

    我有两个输入 用于存储来自谷歌地图脚本的纬度和经度 如果用户更改标记的位置 gt 这两个输入将获取用户所啄的纬度和经度 所以我想获取这两个输入的值 我尝试了 v model 但它不起作用我实际上注意到 只有当我通过键入或粘贴某些内容来更改这
  • CMD.EXE 批处理脚本显示 txt 文件中的最后 10 行

    有什么想法如何回显或输入 txt 文件的最后 10 行吗 我正在运行服务器更改日志脚本来提示管理员说明他们正在做什么 以便我们可以跟踪更改 我试图让脚本显示最近 10 个条目左右 以了解最近发生的情况 我找到了一个处理最后一行的脚本 如下所
  • Android 从gridview布局索引转换成行和列

    如果我有从 0 开始的网格上位置的索引 如何将其转换为行 列 我得到以下错误结果 幸运的是 我知道我有多少行和列 在我的例子中是 11 x 11 int column position columns int row position co
  • 每个服务端点的 HttpClient 实例化

    实例化 HttpClient 时 一个常见的建议是 使用单例 每次使用后不要丢弃 https stackoverflow com questions 22560971 what is the overhead of creating a n
  • 将 Angular-Seed Jasmine 单元测试转换为 CoffeeScript

    作为练习 我正在尝试转换包含在angular seed从 js 回购到咖啡脚本 特别是 我遇到了问题tests unit directivesSpec js测试集 定义了一个简单的价值服务 这是我的咖啡脚本代码 1 describe dir
  • 如何检测 Gradle 构建是否正在 TeamCity 上运行?

    一些日志消息 https www jetbrains com help teamcity service messages html我的构建脚本中的内容仅当 Gradle 构建在 TeamCity 上运行时才相关 如何以编程方式检测 Gra
  • OLE DB 提供程序“Search.Collat​​orDSO”返回“命令未准备好”

    有人能够使用 OLE DB 提供程序在 SQL Server 中进行搜索来连接到 Windows 搜索服务吗 下面您将看到我在 Management Studio 中配置链接服务器时不断遇到的错误消息 链接服务器 TESTSERVER 的
  • 无序列表

    就 SEO 和可访问性而言 ul 这是构建简单导航菜单的好方法吗 作为参考 我尝试通过 Lynx 测试我的所有网站 只是为了帮助确保可访问性 并且 ul 就 Lynx 中的显示而言 s 似乎是最充分的 但这真的可以用作 SEO 的良好经验法
  • C++ ABI 如何处理 RVO 和 NRVO?

    我对编译器和链接器如何处理调用要求这一事实感到困惑er该功能的不同取决于该功能是否使用 RVO 还是 NRVO 这可能是我的误解 但我的假设是通常没有 RVO 或 NRVO std string s get string 如果 get st