g++:在涉及多个翻译单元的情况下 RVO 如何工作

2024-04-17

首先请看下面的代码,它由2个翻译单元组成。

--- foo.h ---

class Foo
{
public:
    Foo();
    Foo(const Foo& rhs);
    void print() const;
private:
    std::string str_;
};

Foo getFoo();

--- foo.cpp ---
#include <iostream>

Foo::Foo() : str_("hello")
{
    std::cout << "Default Ctor" << std::endl;
}

Foo::Foo(const Foo& rhs) : str_(rhs.str_)
{
    std::cout << "Copy Ctor" << std::endl;
}

void Foo:print() const
{
    std::cout << "print [" << str_ << "]" << std:endl;
}

Foo getFoo()
{
    return Foo(); // Expecting RVO
}

--- main.cpp ---
#include "foo.h"

int main()
{
    Foo foo = getFoo();
    foo.print();
}

请确保 foo.cpp 和 main.cpp 是不同的翻译单元。因此,根据我的理解,我们可以说翻译单元 main.o (main.cpp) 中没有可用的 getFoo() 实现细节。

然而,如果我们编译并执行上面的代码,我看不到“Copy Ctor”字符串,这表明 RVO 在这里工作。

如果你们中的任何人请让我知道即使“getFoo()”的实现细节没有暴露给翻译单元 main.o,如何实现这一点,我将不胜感激。

我使用GCC(g++)4.4.6进行了上述实验。


编译器只需一致地工作即可。

换句话说,编译器必须只查看返回值type,并根据该类型,决定返回该类型对象的函数如何返回该值。

至少在典型情况下,该决定是fairly琐碎的。它预留一个寄存器(或可能两个)用于返回值(例如,在 Intel/AMD x86/x64 上,通常为 EAX 或 RAX)。任何足够小的类型都将返回那里。对于任何太大而无法容纳的类型,该函数将接收一个隐藏的指针/引用参数,告诉它将返回结果存放在哪里。请注意,这在完全不涉及 RVO/NRVO 的情况下也适用——事实上,它同样适用于返回 a 的 C 代码struct就像 C++ 返回一个class目的。虽然返回一个struct在 C 中可能不像在 C++ 中那么常见,但它仍然是允许的,并且编译器必须能够编译执行此操作的代码。

实际上有两个单独的(可能的)副本可以被消除。一是编译器可能会在堆栈上为本地保存返回值分配空间,然后从那里复制到返回期间指针引用的位置。

第二个可能是从该返回地址复制到该值真正需要结束的其他位置。

第一个在函数本身内部被消除,但对其外部接口没有影响。它最终将数据放置在隐藏指针告诉它的位置——唯一的问题是它是否首先创建本地副本,或者总是直接使用返回点。显然,使用 [N]RVO,它总是直接起作用。

第二种可能的复制是从(潜在的)临时复制到值真正需要结束的地方。这是通过优化调用序列而不是函数本身来消除的——即,为函数提供一个指向该返回值的最终目的地的指针,而不是某个临时位置,编译器将从该临时位置将值复制到其目的地。

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

g++:在涉及多个翻译单元的情况下 RVO 如何工作 的相关文章

随机推荐

  • C:scanf循环

    char buf 1024 0 send a message if status 0 while 1 printf Enter message scanf 1023 n buf fflush stdin if strcmp buf quit
  • SQL Server 图形数据库 - 使用多种边类型的最短路径

    我已经对 SQL Server GraphDB 进行了研究 但到目前为止我发现的所有人为示例仅使用单个边缘表 总是如此Person friend of gt Person 例如 就我而言 我创建了数据中心中已部署软件组件的图表 并且存在不同
  • Android - 如何在启动后启动 /sdcard 上的应用程序

    有没有一种方法可以在启动后自动启动Android应用程序 如果它位于Android应用程序上 sdcard 好吧 大概是通过BroadcastReceiver 但哪种行动是正确的呢 ACTION BOOT COMPLETED does no
  • Html.ActionLink 无法动态调度

    我的 MVC3 有问题 我正在尝试使用 Html ActionLink 为我的博客项目中的标题生成链接 在中使用常量字符串ActionLink效果很好 但如果我使用Posts Title 当前帖子模型的标题被循环 我得到这个异常 CS197
  • 如何减少flutter web应用程序的加载时间

    截至目前 我们可以将 flutter web 应用程序作为单个文件启动 该文件将立即加载 因此需要花费大量时间和带宽来加载 这并不理想 有没有办法一次只加载一个页面 而不是整个网络应用程序 我的意思是 一次加载一个小部件 任何建议将不胜感激
  • 卡夫卡高级消费者 error_code=15

    当尝试使用高级消费者 使用全新的消费者组 从 Kafka 进行消费时 消费者永远不会开始运行 当我将日志记录级别切换为调试时 我可以看到以下两行一遍又一遍地重复 DEBUG AbstractCoordinator 09 43 51 192
  • 了解跟踪*

    再会 当试图理解数学使用标准的评估顺序Trace and TraceScan最近开发的命令及其漂亮的视觉表示thread https stackoverflow com questions 5459735 the clearest way
  • foreach(... in ...) 或 .ForEach();这就是问题[重复]

    这个问题在这里已经有答案了 可能的重复 C foreach 与函数式each https stackoverflow com questions 2024305 c sharp foreach vs functional each 这是一个
  • C# 中是否有一个好的浮点数基数排序实现

    我有一个带有浮点类型字段的数据结构 这些结构的集合需要按浮点值排序 是否有一个基数排序实现 如果没有 是否有一种快速的方法来访问指数 符号和尾数 因为如果你首先对尾数 指数和最后一次的指数对浮点数进行排序 您对浮点数进行排序的时间复杂度为
  • 是否有适用于触摸移动设备的 HTML5/ jQuery 球形全景查看器

    我需要将球形全景查看器放入 Web 应用程序中 最好是 HTML5 和 jQuery 用户必须能够使用手指在全景图中移动 有谁知道有类似的东西可以使用 只需支付少量费用或更好地免费 这是一个老问题 但对于现在找到它的人 像我一样 我认为 P
  • FirebaseImageLoader 不下载图像

    我正在尝试从 ViewHolder 内部的存储中下载图像 但它不起作用 FirebaseStorage storage FirebaseStorage getInstance StorageReference storageReferenc
  • 如何使用多色热图解决 MemoryError

    我试图通过从文件中读取数据来绘制具有多种颜色的热图 我可以很好地生成 2D 和法线热图 但无法绘制如附图所示的图像 当使用随机数时 我可以绘制此图 但在从文件中读取数据时 它显示错误 上面的热图是用随机数据生成的 Input col 1 a
  • 如何更改存储在字符串中的日期格式?目标c [重复]

    这个问题在这里已经有答案了 可能的重复 如何转换 NSString 中的日期时间格式 https stackoverflow com questions 2076417 how to convert datetime format in n
  • @use 即将推出,但此版本的 Dart Sass 不支持它

    我在跑步ng serve包含 Sass 的 Angular cli 项目 我一直在使用 import and include没有问题 当我添加时 use 终端抛出 use 即将推出 但此版本的 Dart 不支持它 萨斯 我的 package
  • 带列表框的 WPF ScrollViewer

    需要你的帮助 我有一个列表框 带有虚拟化 显示一个 ScrollViewer 我的列表框项目是可展开的 展开时它们的高度可能会超出可见的滚动区域 我遇到的问题是 当列表框项目超出可见滚动区域时 滚动会跳转到下一个列表框项目 而不是简单地滚动
  • 在 UITableView 的 header 中添加一个 UIButton

    我需要在动态填充的 UIViewTable 的正上方放置一个按钮 不填充第一个单元格 第 0 行 而是利用标题区域感觉是正确的 因此我使用 UITableViewDelegate 方法以编程方式创建一个包含 UIButton 的 UIVie
  • 如何在 Objective-C 中创建 NSNotification 对象?

    我想创建一个 NSNotification 对象 如下所示 NSNotification obj NSNotification alloc init 但是当我像这样创建时 我收到一个异常 NSConcreteNotification ini
  • 高性能QImage输出显示

    我正在尝试将视频输出 帧序列 到任何 qt 可见小部件 一开始我认为 QLabel 足以满足这一点 但我错了 对于处理大图像 例如 1080p 的处理器来说 转换为像素图过于过载 还有其他解决方案吗 不是QLabel 一帧的代码示例 QIm
  • java.lang.UnsupportedOperationException:无法将索引 5 处的值转换为颜色:type=0x5

    我的应用程序更新后崩溃了Android Studio 3 RC1 Gradle4 安卓Gradle插件 3 RC2 This is the error I am having java lang RuntimeException Unabl
  • g++:在涉及多个翻译单元的情况下 RVO 如何工作

    首先请看下面的代码 它由2个翻译单元组成 foo h class Foo public Foo Foo const Foo rhs void print const private std string str Foo getFoo foo