C++链接器会自动内联函数(没有“inline”关键字,没有在标头中实现)吗?

2024-01-10

C++ 链接器是否会自动内联“传递”函数,这些函数未在标头中定义,并且未明确请求通过inline关键词?

例如,发生以下情况so often,并且应该always受益于“内联”,似乎每个编译器供应商都应该通过链接器通过“内联”“自动”处理它(在可能的情况下):

//FILE: MyA.hpp
class MyA
{
  public:
    int foo(void) const;
};

//FILE: MyB.hpp
class MyB
{
  private:
    MyA my_a_;
  public:
    int foo(void) const;
};

//FILE: MyB.cpp
// PLEASE SAY THIS FUNCTION IS "INLINED" BY THE LINKER, EVEN THOUGH
// IT WAS NOT IMPLICITLY/EXPLICITLY REQUESTED TO BE "INLINED"?
int MyB::foo(void)
{
  return my_a_.foo();
}

我知道 MSVS 链接器将通过其执行一些“内联”链接时间代码生成 (LTGCC),并且 GCC 工具链还支持链接时间优化 (LTO) (see: 链接器可以内联函数吗? https://stackoverflow.com/questions/5987020/can-the-linker-inline-functions).

此外,我知道在某些情况下,这cannot被“内联”,例如当实现对链接器不“可用”时(例如,跨共享库边界,发生单独链接)。

但是,如果这是代码链接到single不跨越 DLL/共享库边界的可执行文件,我会expect编译器/链接器供应商自动地内联函数,作为一种简单而明显的优化(对性能和大小都有好处)?

我的希望是不是太天真了?


这是对您的示例的快速测试(使用MyA::foo()简单地返回的实现42)。所有这些测试都是针对 32 位目标进行的 - 64 位目标可能会出现不同的结果。还值得注意的是,使用-flto选项(GCC)或/GL选项 (MSVC) 可实现全面优化 - 无论在何处MyB::foo()被调用,它只是被替换为42.

使用 GCC(MinGW 4.5.1):

gcc -g -O3 -o test.exe myb.cpp mya.cpp test.cpp

对 MyB::foo() 的调用没有被优化掉。MyB::foo()本身稍微优化为:

Dump of assembler code for function MyB::foo() const:
   0x00401350 <+0>:     push   %ebp
   0x00401351 <+1>:     mov    %esp,%ebp
   0x00401353 <+3>:     sub    $0x8,%esp
=> 0x00401356 <+6>:     leave
   0x00401357 <+7>:     jmp    0x401360 <MyA::foo() const>

这是条目序言保留在原处,但立即撤消(leave指令)并且代码跳转到 MyA::foo() 来完成真正的工作。然而,这是一个优化compiler(不是链接器)正在做,因为它意识到MyB::foo()只是返回任何内容MyA::foo()返回。我不知道为什么要留下序言。

MSVC 16(来自 VS 2010)的处理方式略有不同:

MyB::foo()最终以两次跳跃结束——一次跳跃到某种“重击”:

0:000> u myb!MyB::foo
myb!MyB::foo:
001a1030 e9d0ffffff      jmp     myb!ILT+0(?fooMyAQBEHXZ) (001a1005)

重击声直接跳到了MyA::foo():

myb!ILT+0(?fooMyAQBEHXZ):
001a1005 e936000000      jmp     myb!MyA::foo (001a1040)

再说一遍 - 这很大程度上(全部?)由编译器执行,因为如果您查看链接之前生成的目标代码,MyB::foo()被编译为普通跳转MyA::foo().

因此,归结为所有这些 - 看起来在没有显式调用 LTO/LTCG 的情况下,今天的链接器不愿意/无法执行删除调用的优化MyB::foo()总的来说,即使MyB::foo()是一个简单的跳转MyA::foo().

所以我想如果你想要链接时间优化,请使用-flto(对于海湾合作委员会)或/GL(对于 MSVC 编译器)和/LTCG(对于 MSVC 链接器)选项。

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

C++链接器会自动内联函数(没有“inline”关键字,没有在标头中实现)吗? 的相关文章

随机推荐

  • 如何使用Python下载股票价格数据?

    我已经安装了pandas datareader但我想知道是否还有其他选择 到目前为止 我正在使用这个 import pandas datareader data as web start date 2018 01 01 end date 2
  • 签名扫描

    许多防病毒程序使用基于签名的恶意软件检测 这是为 ClamAV 创建签名 http www clamav net doc webinars Webinar Alain 2009 03 04 pdf 考虑到整个文件是恶意软件 我可以理解他们如
  • 如何加载用户.bashrc的RVM部分以在Apache下运行Ruby CGI脚本?

    我在 Ubuntu 12 04 上配置了一个新服务器 并开始使用 RVM 我已经按照我的用户 作为我自己 而不是使用 sudo 作为 root 安装了 RVM瑞安 比格的指南 http ryanbigg com 2010 12 ubuntu
  • R/Stringr 在第 n 次出现“_”后提取字符串,并以第一次出现“_”结束

    使用 R 和 stringr 包 或任何其他与此相关的包 我想在第 n 次出现 后提取字符串 并以第一次出现 结束 例如 df lt c J J HERE jfdkaldjhieuwui blahblah ffd THIS fjdkalfj
  • 如何生成新的GUID?

    我正在开发一个网络服务 需要一个新的GUID 作为对服务内方法的引用传递 我不熟悉C or the GUID object 但需要类似的东西PHP 因此创建一个新对象 根据我的理解 它返回一个empty blank GUID 有任何想法吗
  • 如何避免谷歌条形图中的条形标签重叠?

    我正在创建一个堆积条形图 需要显示堆栈内的标签 但很少有标签被重叠 以供参考image https i stack imgur com gGKG9 jpg 你能帮助我如何避免使用谷歌图表重叠吗 div div
  • if else key 分割 JSON

    我有这个功能 let input Apples Apples 501 82 Apples pos2 502 61 Apples pos3 502 61 Apples 502 16 let output Object keys input r
  • 拖动项目时触发的 click 事件 (Firefox)

    当我单击一个项目时 我可以编辑该字段 这要归功于引导程序可编辑 http vitalets github com bootstrap editable 当我拖放项目时 我可以更改项目的位置 这要归功于jquery ui sortable h
  • PhpStorm 中文件名旁边的神秘数字图标[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我不小心按下了 PhpStorm 中的热键 现在我的一个文件名旁边有一个小数字图标 这是什么意思 我该如何删除它 这是一个屏幕截图 这是什
  • 查询在 while 循环中无法正常工作

    我有一个 While 循环 我试图插入 DECLARE CurrentOffer int 121 DECLARE OldestOffer int 115 DECLARE MinClubcardID bigint 0 DECLARE MaxC
  • PHP脚本在特定时间执行

    有没有一种简单的方法可以让 php 脚本在一天中的特定时间执行一些 html 例如 我的主页上有一个标题 有时我希望能够在标题下方添加一些内容 在本例中是一个 iframe 我知道每个人都提到了 cron 作业 但是这将如何工作呢 还有替代
  • 使用 CSS3 过渡的动画 jQuery UI 可排序

    我如何使用 CSS3 过渡 或任何其他方式 来制作jQuery 可排序 http jqueryui com sortable 其行为更像是 iOS 中的列表重新排序 其中列表项在拖动时会平滑地进行动画处理 因此当您拖动时 项会迅速移开 编辑
  • dc.js barChart 第一个和最后一个栏未完全显示

    我有一个条形图d3 time scalex 轴 我每小时显示一些数据 但使用时第一个和最后一个数据点条总是被切成两半centerBar true 当使用centerBar false 最后一个栏完全消失 时间窗口基于数据本身 计算如下 va
  • Apache Spark 中的递归方法调用

    我正在从 Apache Spark 上的数据库构建一个家谱 使用递归搜索来查找数据库中每个人的最终父级 即家谱顶部的人 假设搜索 id 时返回的第一个人是正确的父母 val peopleById peopleRDD keyBy f gt f
  • 给react中的动态数组元素一个图标

    我有一个动态数量的数组 例如 1 2 3 5 7 1 2 3 2 7 8 其中元素代表平台 ID 有助于唯一识别 PlayStation Xbox 等平台 I want to link a react icon https react ic
  • DirectX:如何绘制平滑的 2D 水(基于粒子的水)

    我最近使用粒子 1000 1500 工作 使用斯托克斯方程 进行水模拟 但我的问题是我使用 IDXSprite 它只是使用蓝色纹理四边形 7x7 绘制粒子 看起来不太平滑 是否有任何方法或已知技术来绘制此类系统 使表面看起来光滑 并且水不应
  • 如何更新 ActiveStorage 中的附件 (Rails 5.2)

    我最近将我的项目升级到最新的 Rails 版本 5 2 以获得ActiveStorage 一个处理附件上传到云服务 如 AWS S3 Google Cloud 等 的库 几乎一切都工作正常 我可以上传并附加图像 user avatar at
  • C#:使用具有多个图像的 .ico 文件

    我试图从包含两个图标的 ico 文件中设置 C 中的 TreeView 中的图像 32x32 版本和 16x16 版本 图像正在设置 但 Net 选择 32x32 版本 并将其缩小 看起来很糟糕 而不是选择现成的 16x16 图像 相关代码
  • aspnet core 中的部分视图发布子模型?

    我有一个视图 其中包含包含各种不同部分的选项卡 我将每个选项卡实现为部分视图 有一个 ViewModel 它具有各种子类来填充选项卡中的视图和部分视图 FormCaptureViewModel FormDetailViewModel For
  • C++链接器会自动内联函数(没有“inline”关键字,没有在标头中实现)吗?

    C 链接器是否会自动内联 传递 函数 这些函数未在标头中定义 并且未明确请求通过inline关键词 例如 发生以下情况so often 并且应该always受益于 内联 似乎每个编译器供应商都应该通过链接器通过 内联 自动 处理它 在可能的