C++ 入门篇(七) 内联函数

目录

一、概念   

二、内联函数的展开

三、注意事项

【总结】 


一、概念   

1.内联函数是什么?

        以inline修饰的函数叫做内联函数。


2.为什么?
        
内联函数本质上是对宏的优化,是C++用来替代宏函数的。
     

        编译时C++编译器会在调用该函数的地方展开内联函数。没有函数调用建立栈帧的开销,内联函数提升程序运行的效率(内联函数展开后可直接编译,省去了调用函数建立栈(call 函数这一步骤)帧花费额外的开销)。


3.怎么用?

        定义简单函数(短小、无递归、声明和定义没有分离)时在返回值类型前面加上inline。    


二、内联函数的展开

         inline对于编译器而言只是一个建议 ,不同编译器关于 inline 实现机制可能不同 ,一般建议:将 函数规 模较小 ( 即函数不是很长,具体没有准确的说法,取决于编译器内部实现 ) 不是递归、频繁调用 的函数采用inline 修饰,否则编译器会忽略 inline 特性。

eg. 下图为《 C++prime 》第五版关于 inline 的建议:

 eg. inline只会在符合条件的情况下,在调用的地方展开。

Add、func函数的汇编指令:

(注,VS编译器要看到内联函数的汇编指令,必须先在 属性->优化->内联函数扩展中 把默认改为 只 适用于_inline。)

Add、func函数的汇编指令和代码的对应图:

通过观察Add、func函数的汇编指令来判断函数是否被展开:
很明显Add函数被展开,但func函数是被调用,未展开。(call func就是在调用func函数)

        不展开的最大的一个原因就是,展开后会让编译的程序暴增,因为内联是一种以空间换时间的做法。
        如以下例子,Func函数有100行指令,调用Func函数1万次,不展开就只有1W条调用Func函数的call指令,如果展开就是1W*100行指令。


三、注意事项

        1. inline不能将声明和定义分离,分离会导致链接错误。因为如果inline被展开,编译时的符号表中就不会记录该函数的地址,链接时就会找不到该函数,产生链接错误(Link_error)。(在编译时内联函数已经被展开,其地址不会放进符号表里面,没有地址故无法通过声明找到其定义。如果一定要分离定义,建议直接将内联函数定义在头文件中。)

        2. 内联函数在debug模式下不会替换(展开),因为这样更方便编程者调试,在release模式下就会对内联函数进行替换(展开),在编译时我们就不会看到call内联函数了(即不会再建立栈帧)。

        3. 可以在同一个项目的不同源文件内定义函数名相同但实现不同的inline函数,因为inline函数会在调用的地方展开,所以符号表中不会有inline函数的符号名,不存在链接冲突。

        4. 再次强调,inline只是一种建议,函数会不会展开需要看此函数是否符合当前编译器对内联函数的要求。


【总结】 


------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烛火萤辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值