C++ 编译器会优化重复的函数调用吗?

2024-04-21

编译器(通常或特别)是否优化重复的函数调用?

例如,考虑这种情况。

struct foo {
  member_type m;
  return_type f() const; // returns by value
};

函数定义在一个翻译单元中

return_type foo::f() const {
  /* do some computation using the value of m */
  /* return by value */
}

重复的函数调用在另一个单元中

foo bar;

some_other_function_a(bar.f());
some_other_function_b(bar.f());

第二个翻译单元中的代码会转换成这样吗?

foo bar;

const return_type _tmp_bar_f = bar.f();

some_other_function_a(_tmp_bar_f);
some_other_function_b(_tmp_bar_f);

潜在地,计算f确实可能很昂贵,但返回的类型可能非常小(考虑一个数学函数返回一个double)。编译器会这样做吗?有这样做或不这样做的情况吗?您可以考虑这个问题的通用版本,而不仅仅是成员函数或不带参数的函数。

根据 @BaummitAugen 的建议进行澄清:

我对这里问题的理论方面更感兴趣,而不是是否可以依靠它来使现实世界的代码运行得更快。我对 Linux 上 x86_64 上的 GCC 特别感兴趣。


如果您启用了链接时间优化并且优化级别足够高,GCC 绝对可以跨编译单元进行优化,请参见此处:https://gcc.gnu.org/wiki/LinkTimeOptimization https://gcc.gnu.org/wiki/LinkTimeOptimization除了编译时间之外,确实没有理由不执行这两件事。

此外,您始终可以通过使用适当的属性标记函数来帮助编译器。您可能想使用属性 const 来标记该函数,如下所示:

struct foo {
  member_type m;
  return_type f() const __attribute__((const)); // returns by value
};

请查看此处的 GCC 文档,了解哪个属性合适:https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html

从更一般的意义上来说,编译器很容易检测到这一点。它实际上执行不太明显的转换。然而,链接时间优化之所以重要的原因是,一旦 GCC 生成了实际的机器代码,它就不会真正知道此时做什么是安全的。例如,您的函数可以修改数据(在您的类之外)或访问易失性变量。

EDIT:

GCC 绝对可以做到这一点优化。使用此代码和标志 -O3 -fno-inline:

C++代码:

#include <iostream>

int function(int c){
  for(int i = 0; i != c; ++i){
    c += i;
  }
  return c;
}

int main(){
  char c;
  ::std::cin >> c;
  return function(c) + function(c) + function(c) + function(c) + function(c);
}

装配输出:

4006a0: 48 83 ec 18             sub    rsp,0x18
4006a4: bf 80 0c 60 00          mov    edi,0x600c80
4006a9: 48 8d 74 24 0f          lea    rsi,[rsp+0xf]
4006ae: e8 ad ff ff ff          call   400660 <_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_RS3_@plt>
4006b3: 0f b6 7c 24 0f          movzx  edi,BYTE PTR [rsp+0xf]
4006b8: e8 13 01 00 00          call   4007d0 <_Z8functioni>
4006bd: 48 83 c4 18             add    rsp,0x18
4006c1: 8d 04 80                lea    eax,[rax+rax*4]
4006c4: c3                      ret    
4006c5: 66 66 2e 0f 1f 84 00    data32 nop WORD PTR cs:[rax+rax*1+0x0]
4006cc: 00 00 00 00 

但是,当函数位于单独的编译单元中并且未指定 -flto 选项时,它确实无法执行此操作。只是为了澄清一下,这一行调用了该函数:

call   4007d0 <_Z8functioni>

此行将结果乘以 5(将五个副本加在一起):

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

C++ 编译器会优化重复的函数调用吗? 的相关文章

  • 我可以使用反射更改 C# 中的私有只读字段吗?

    我想知道 由于很多事情都可以使用反射完成 我可以在构造函数完成执行后更改私有只读字段吗 注 只是好奇 public class Foo private readonly int bar public Foo int num bar num
  • 将 2D 数组映射到 1D 数组

    我想用一维数组来表示一个二维数组 函数将传递两个索引 x y 和要存储的值 这两个索引代表一维数组的单个元素 并相应地设置它 我知道一维数组需要具有 arrayWidth arrayHeight 的大小 但我不知道如何设置每个元素 例如 如
  • 处理 LINQ sum 表达式中的 null

    我正在使用 LINQ 查询来查找列的总和 并且在少数情况下该值有可能为空 我现在使用的查询是 int score dbContext domainmaps Where p gt p SchoolId schoolid Sum v gt v
  • 为什么C Clock()返回0

    我有这样的事情 clock t start end start clock something else end clock printf nClock cycles are d d n start end 我总是得到输出 时钟周期是 0
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • 我应该在单元测试中使用 AutoMapper 吗?

    我正在为 ASP NET MVC 控制器方法编写单元测试 这些控制器依赖于IMapper 我创建的用于抽象 AutoMapper 的接口 使用 Castle Windsor 通过构造函数注入传入 动作方法使用IMapper从领域对象映射到
  • 身份未映射异常

    System Security Principal IdentityNotMappedException 无法转换部分或全部身份引用 该错误仅在应用程序注册后出现一次 当 SecurityIdentifier 无法映射时 例如 返回 Ide
  • 字节到二进制字符串 C# - 显示所有 8 位数字

    我想在文本框中显示一个字节 现在我正在使用 Convert ToString MyVeryOwnByte 2 但是 当字节开头有 0 时 这些 0 就会被删除 例子 MyVeryOwnByte 00001110 Texbox shows g
  • 如何避免选择项目时 winforms 树视图图标发生变化

    我正在一个小型 C Winforms 应用程序中尝试树视图 我已经以编程方式将 ImageList 分配给树视图 并且所有节点都很好地显示了它们的图标 but当我单击一个节点时 它的图标会发生变化 变为 ImageList 中的第一个图像
  • glDrawElements 只绘制半个四边形

    这是我的功能 void Object draw2 if mIsInitialised return Tell OpenGL about our vertex and normal data glEnableClientState GL VE
  • C#:使用 System.Text 和 System.Text.RegularExpressions 之间的区别

    在 ASP NET C 应用程序中 我注意到为了使用 Regex 和 StringBuilder 我必须将两者都放在 using System Text using System Text RegularExpressions 从简单的角度
  • 当格式字符串包含“{”时,String.Format 异常

    我正在使用 VSTS 2008 C Net 2 0 执行以下语句时 String Format 语句抛出 FormatException 有什么想法是错误的吗 这是获取我正在使用的 template html 的位置 我想在 templat
  • 使用 AutoMapper 进行 LINQ GroupBy 聚合

    试图让查询工作 但老实说不确定如何 或者是否可能 进行它 因为我尝试过的一切都不起作用 共查询6个表 Person PersonVote PersonCategory Category City FirstAdminDivision Per
  • 为什么 C 函数不能返回数组类型?

    我是 C 语言新手 想知道 为什么 C 函数不能返回数组类型 我知道数组名是数组第一个值的地址 而数组是 C 中的二等公民 您自己已经回答了这个问题 数组是二等公民 C 按值返回 数组不能按值传递 因此不能返回它们 至于为什么数组不能按值传
  • 如何使用 Clang 查找内存泄漏

    我在我的机器 ubuntu 中安装了 Clang 以便发现我的 C 代码中的内存泄漏 我编写了一个示例代码来检查它的工作情况 如下所示 File hello c for leak detection include
  • 为什么我不能在扩展 List 的类中调用 OrderBy?

    我有一堂课 Deck 其中包含一个名为的方法Shuffle 我正在致力于重构Deck延长List
  • 在 MVVM 中,可以在视图后面的代码中访问 ViewModel 吗?

    在 MVVM 模式中 是否可以接受甚至可以访问视图代码后面的 ViewModel 属性 我有一个可观察的集合 它填充在 ViewModel 中 我需要在视图中使用它来绑定到带有链接列表的无限滚动条 IE private LinkedList
  • SSBO 是更大的 UBO?

    我目前正在 OpenGL 4 3 中使用 UBO 进行渲染 以将所有常量数据存储在 GPU 上 诸如材料描述 矩阵等内容 它可以工作 但是 UBO 的小尺寸 我的实现为 64kB 迫使我多次切换缓冲区 减慢渲染速度 我正在寻找类似的方法来存
  • 宏观评价[重复]

    这个问题在这里已经有答案了 可能的重复 未定义的行为和序列点 https stackoverflow com questions 4176328 undefined behavior and sequence points 我无法理解以下宏
  • 多个同名内存数据库

    关系到这个答案 https stackoverflow com a 48446491 596758 我试图通过设置让多个上下文工作UseInMemoryDatabase以同名 下面的测试失败 第二个上下文为空 我还需要做什么才能在内存数据库

随机推荐

  • Git 到 TFS 2008 的单向迁移(有历史记录)

    我是 Git 的新手 我正在探索 Git 存储库到 TFS 的单向一次性迁移 有历史记录 我正在研究插件git tfs https github com git tfs git tfs 我找不到关于这个特定场景的任何帮助 维基 博客 在这种
  • 我可以对未映射到表的实体使用 Hibernate 查询语言吗?

    以下是我用来检索的 mySQL 查询HolidayPackages for a given Hotel SELECT pkg idHolidayPackage pkg name FROM holidaypackage pkg INNER J
  • 在 64 位机器中创建 32 位 JavaFx Native Bundle

    我的机器和 IDE 的配置如下 产品版本 NetBeans IDE 7 2 内部版本 201207171143 爪哇 1 7 0 07 Java HotSpot TM 64 位服务器虚拟机 23 3 b01 系统 Windows 7 版本6
  • Pyramid.security:使用 unauthenticated_userid(request) 从数据库获取用户信息真的安全吗?

    我正在尝试使用 Pyramid 文档创建可访问的用户数据缓存 使 用户对象 可用作请求属性 http docs pylonsproject org projects pyramid cookbook en latest auth user
  • Spring 表达语言的映射

    我想使用 SpEL 来评估一些谓词 由于值 属性是动态的 因此我没有特定的 bean 类 因此 我们有一个 hashmap 其中 根据应用程序状态 键映射到不同的 POJO bean 例如 Person person new Person
  • Git 推送失败,“非快进更新被拒绝”

    我已经通过 Git Online 编辑了我的 GIT 存储库 当我尝试推送本地代码更改后 出现错误 Git push failed To prevent from losing history non fast forward update
  • Oracle中如何检查所有字段是否唯一?

    Oracle中如何检查所有字段是否唯一 SELECT myColumn COUNT FROM myTable GROUP BY myColumn HAVING COUNT gt 1 如果出现次数大于 1 即它们不是唯一的 这将返回所有 my
  • Java 中的数据验证和扫描器

    我有一个关于数据验证和扫描仪的问题 下面的代码检查用户输入 除了整数之外的任何内容都是不允许的 并且要求用户重新输入一个值 我的问题是 只有当扫描仪打开时 代码才有效在 while 循环内声明 如果在外部声明扫描仪 则程序将无限执行 这是为
  • 如何在.net core项目中使用SignalR Core监听postgresql数据库?

    我正在开发 net core Web 应用程序 我想监听我的 PostgreSQL 数据库 如果桌面上有任何变化 我必须得到它 所以根据我的研究 我必须使用SignalR Core 我用 SignalR 做了一些示例应用程序 例如聊天应用程
  • pod init 获得未初始化的常量 ActiveSupport::XmlMini::IsolatedExecutionState (NameError)

    mac os 成功安装cocoapods 1 11 2 红宝石 v ruby 3 1 1p18 2022 02 18 修订版 53f5fc4236 x86 64 darwin21 宝石 v 3 3 8 但 exec pod init 收到错
  • django 管理中的多态行为

    问题 假设我有三个类A B和C 其中B是A的子类 C是B的子类 A lt B lt C 当我打开管理并列出所有 A 时 我看到所有 A B 和 C 但是 当我点击其中一个链接查看详细信息并编辑该特定 B 时 我只会看到 B 的字段 即使该实
  • 突出显示用户选择的文本片段

    我有一个 div with some text div 我需要突出显示用户选择的文本片段 我已经部分实现了这个 这是我的代码 http jsfiddle net Greatshock fy09jo8w 8 thisRespondHightl
  • 能否在上传 Azure CloudBlockBlob 的同时在其上设置元数据?

    我目前使用以下方式上传 CloudBlockBlob CloudBlockBlob UploadFromStreamAsync 然后我立即在上面设置了一堆用户元数据 问题是 我有一个事件网格事件 该事件在上传 blob 时触发 但事件处理程
  • 如何在多个 HTML 页面上播放背景音频?

    是否有解决方案可以让背景音频 音乐在网站上的多个页面上播放 而无需在每个页面加载时重新启动 该网站当前使用框架集 但我正在寻找替代方案 如果不让整个网站都 AJAX 我认为框架是唯一的方法 如果您需要的话 这里有一个关于制作 ajax 站点
  • JavaScript 多行字符串[重复]

    这个问题在这里已经有答案了 问题是 像在 PHP 中一样将多行字符串存储到变量中的 JavaScript 方法是什么 如果 多行字符串 是指包含换行符的字符串 则可以通过使用转义它们来编写这些字符串 n 对于换行符 var multilin
  • 如何从命令行将 Svelte 文件编译为 JavaScript?

    我是新来的Svelte https svelte dev 快速提问 Svelte 编译器有 CLI 吗 如何访问它 我知道 Svelte 有一个使用 rollup 的预配置设置 但不使用什么 用于构建应用程序 一切都很好 但我只需要 CLI
  • Sublime Text 2 在 Java 开发方面是否胜过 Eclipse [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 是时候使用 Django 1.5 了吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • a += b 与 a = a + b 不同[重复]

    这个问题在这里已经有答案了 可能的重复 为什么 在列表上表现异常 https stackoverflow com questions 2347265 why does behave unexpectedly on lists 今天我发现了P
  • C++ 编译器会优化重复的函数调用吗?

    编译器 通常或特别 是否优化重复的函数调用 例如 考虑这种情况 struct foo member type m return type f const returns by value 函数定义在一个翻译单元中 return type f