当程序执行函数调用指令时,CPU将存储该函数调用后指令的内存地址,将函数的参数复制到堆栈上,最后将控制权转移到指定的函数。然后,CPU执行函数代码,将函数返回值存储在预定义的内存位置/寄存器中,并将控制权返回给调用函数。如果函数的执行时间少于从调用者函数到被调用函数(被调用者)的切换时间,则这可能会成为开销。对于大型函数和/或执行复杂任务的函数,与函数运行所花费的时间相比,函数调用的开销通常微不足道。但是,对于小型的常用功能,进行函数调用所需的时间通常比实际执行函数代码所需的时间多得多。对于小功能,由于小功能的执行时间少于切换时间,因此会产生开销。

C++提供了inline函数,以减少函数调用的开销。内联函数是在调用时在行中扩展的函数。调用内联函数时,将在内联函数调用时插入或替换内联函数的整个代码。替换由C++编译器在编译时执行。如果内联函数很小,则可以提高效率。

inline函数看起来像函数,动作像函数,但是又比宏方便很多,调用inline函数省去了参数压栈、生成汇编语言的 CALL调用、返回参数、执行return等过程所花费的额外开销。不过inline函数也有缺点:增加目标码的大小。因为inline函数的设计思想是对该函数的所有调用都用函数本身替换掉,和宏定义一样,但是比宏定义用起来要简单很多。而且inline的调试同样很难。

所以,inline函数对于函数体积很小,却又频繁调用这样的函数来说,可能比函数调用产生的代码更少,但是效率却不可同日而语。有一点需要注意的是:inline只是对编译器提出一个申请,并不是强制命令。编译器可以忽略内联请求。 在以下情况下,编译器可能不会执行内联:

  • 如果函数包含循环。(对于while,do-while)
  • 如果函数包含静态变量。
  • 如果函数是递归的。
  • 如果函数的返回类型不是void,并且函数主体中不存在return语句。
  • 如果函数包含switch或goto语句。

inline可以显示声明,也可以隐式声明。隐式声明方式是将函数定义在类定义之中(函数定义时没有inline关键字),编译器也会当作inline函数。另外,定义在类中的friend函数也会被隐式声明为inline函数。

显式声明的时候必须与函数定义体放在一起才能使函数成为内联,仅将inline放在函数声明前面不起任何作用。定义函数内联的语法为:

inline 

此外,inline函数通常放在头文件中,因为大多数build environments在编译期进行inlining,编译器必须知道函数什么样子才能把函数调用替换成函数本体

大多数virtual函数不能inlining:因为virtual直到运行时才知道调用哪个函数,而inline是在执行前进行替换。此外,对于通过函数指针进行的调用编译器通常不会inlining,下面是一个实例:

inline 

内联函数的优点:

  1. 不会发生函数调用开销。
  2. 调用函数时,还节省了push / pop变量在栈上的开销。
  3. 它还节省了从函数返回调用的开销。
  4. 内联函数时,可以使编译器对函数主体执行特定于上下文的优化。对于正常的函数调用,这种优化是不可能的。通过考虑调用上下文和被调用上下文的流程可以获得其他优化。
  5. 内联函数可能对于嵌入式系统有用(如果很小),因为内联函数所产生的代码少于函数调用的前导和返回。

内联函数的缺点:

  1. 内联函数中添加的变量消耗了额外的寄存器,在内联函数之后,如果要使用寄存器的变量编号增加,则它们可能会增加寄存器变量资源利用的开销。这意味着当在函数调用点替换内联函数主体时,该函数使用的变量总数也会被插入。因此,将用于变量的寄存器数量也将增加。因此,如果函数内联后的变量数急剧增加,则肯定会导致寄存器利用率增加。
  2. 如果使用太多的内联函数,则由于重复执行相同的代码,二进制可执行文件的大小将很大。
  3. 过多的内联也会降低指令Cache命中率,从而降低了从高速缓存到主存储器的指令获取速度。
  4. 如果有人更改了内联函数中的代码,则内联函数可能会增加编译时间开销,然后必须重新编译所有调用位置,这是因为编译器将需要再次替换所有代码以反映更改,否则它将继续使用旧功能。
  5. 内联函数对于许多嵌入式系统可能没有用。因为在嵌入式系统中,代码大小比速度更重要。
  6. 内联函数可能会导致崩溃,因为内联可能会增加二进制可执行文件的大小。内存溢出会导致计算机性能下降。

Note:

  • 将大多数内联限制在小的,经常调用的函数中。这有助于调试和二进制可升级性,最大程度地减少潜在的代码膨胀,并最大程度地提高程序速度。
  • 不要仅仅因为函数模板出现在头文件中就声明inline。

Reference

Effective C++

https://www.geeksforgeeks.org/inline-functions-cpp/

inline函数返回值_C++ inline关键字详解相关推荐

  1. inline函数返回值_C++ 内联函数 inline的详细分析

    1. 什么是内联函数?   就是使用了关键字inline的函数,如 inline int max(int a, int b){ 2. 内联函数有什么作用?   C++在调用函数时,会执行一系列的操作: ...

  2. inline函数返回值_C++知识补充-指针,const,函数指针,指针数组,运算符重载

    嵌入式Linux:C++ 面试准备珍藏版本​zhuanlan.zhihu.com 明月照我心:123道c++笔试题汇总(含答案)​zhuanlan.zhihu.com 阿贵:常见C++笔试面试题整理​ ...

  3. mysql virtual 关键字_C# virtual关键字详解

    C# virtual 是虚拟的含义,在 C# 语言中,默认情况下类中的成员都是非虚拟的,通常将类中的成员定义成虚拟的,表示这些成员将会在继承后重写其中的内容. virtual 关键字能修饰方法.属性. ...

  4. c oracle存储过程返回值,C#调用存储过程详解(带返回值、参数输入输出等)

    本文实例讲述了C#调用存储过程的方法.分享给大家供大家参考,具体如下: CREATE PROCEDURE [dbo].[GetNameById] @studentid varchar(8), @stu ...

  5. python函数用法详解2(变量的作用域(全局变量、局部变量)、共享全局变量、函数返回值、函数的参数(位置参数、关键字参数、默认参数、不定长参数)、拆包、交换变量值、引用、可变和不可变类型)

    1. 变量作⽤域         变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量. 局部变量         定义在函数体内部的变量,即只在函数体内部⽣效. def testA(): ...

  6. Python return函数返回值详解

    Python return函数返回值详解 到目前为止,我们创建的函数都只是对传入的数据进行了处理,处理完了就结束.但实际上,在某些场景中,我们还需函数将处理的结果反馈回来,就好像主管向下级员工下达命令 ...

  7. C语言return的用法详解,C语言函数返回值详解。 (本次转载仅供学习,感谢原创!!转发自C语言中文网,如有侵权请私信本人删除)

    C语言return的用法详解,C语言函数返回值详解 转载:http://c.biancheng.net/view/1855.html 函数的返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这 ...

  8. python函数的用法详解(作用、定义、调用、函数参数、函数返回值、函数说明文档、函数嵌套使用)

    1. 函数的作⽤ 函数就是将⼀段具有独⽴功能的代码块整合到⼀个整体并命名,在需要的位置调⽤这个名称即可完成对应的需求. 函数在开发过程中,可以更⾼效的实现代码重⽤. 2. 函数的使⽤步骤 2.1 定义 ...

  9. go函数详解:函数定义、形参、返回值定义规范、函数内存分析、不支持重载、支持可变参数、基本数据类型和数组默认都是值传递的、支持自定义数据类型、函数返回值命名

    引入 [1]为什么要使用函数: 提高代码的复用型,减少代码的冗余,代码的维护性也提高了 [2]函数的定义: 为完成某一功能的程序指令(语句)的集合,称为函数. [3]基本语法 func 函数名(形参列 ...

最新文章

  1. 用原始方法解析复杂字符串,json一定要用JsonMapper么?
  2. linux kvm安装win7,详解在 KVM 上安装 Win7 虚拟机
  3. dependency 中的 classifier属性
  4. java -uf_Java如何快速修改Jar包里的文件内容
  5. spss多元非线性曲线拟合_快速掌握SPSS数据分析
  6. 常用的Linux操作系统
  7. python变量回收_Python变量的引用、拷贝和回收机制
  8. Cards BZOJ 1004
  9. 中国超级计算机扩大领先优势:TOP500总量首次超越美国
  10. ArcMap 入门教程
  11. 如何以16进制打开dll文件
  12. 登陆界面HTML验证码生成
  13. mysql中获取时间的年月日_Mysql获取系统时间,年,月,日
  14. opencv28:分水岭算法的图像分割
  15. 代码主题darcula_darcula主题模式是()模式。_学小易找答案
  16. google 浏览器同步
  17. 等精度测频原理--频率计
  18. js:根据闰年的判断条件,利用if循环判断闰年
  19. 论文笔记-精读-8.24-Pruning neural networks without any data by iteratively conserving synaptic flow
  20. 故宫学系列之紫禁城:从皇宫到博物院

热门文章

  1. Linux配置kdump大小,linux6下kdump的配置
  2. 《旅行的邀约》摄影展闭展辞
  3. topaz sharpen ai怎么设置为中文
  4. 使用 UNION ALL 注意事项
  5. 是曹国伟选择了阿里巴巴
  6. uniapp关于this.$refs.xxx获取组件出现undefined的解决方法
  7. 个人博客项目Meblog遇到的坑及解决方案
  8. 【rmzt:炫斗之王win7主题】
  9. matlab贝叶斯判别后验概率,贝叶斯公式的直观理解(先验概率/后验概率)
  10. codemirror mysql_Codemirror简单配置