第6课 - 内联函数分析

一、常量与宏回顾

C++中的const常量可以替代宏常数定义,如:

const int A = 3;等价于 #define A 3

那么C++中是否有解决方案替代宏代码片段呢?请看以下内容。

二、内联函数的定义

  1. C++中推荐使用内联函数替代宏代码片段;
  2. C++中使用inline关键字声明内联函数;
  3. 内联函数声明时inline关键字必须和函数定义结合再一起,否则编译器会直接忽略内联请求。内联函数的定义如图1所示:

图1

三、内联函数的特点

  1. C++编译器可以将一个函数进行内联编译,被C++编译器内联编译的函数叫做内联函数;
  2. C++编译器直接将函数体插入函数调用的地方;
  3. 内联函数没有普通函数调用时的额外开销(压栈,跳转,返回);
  4. C++编译器不一定满足函数的内联请求;函数的内联请求可能被编译器拒绝;
  5. 内联函数具有普通函数的特征(参数检查,返回类型等 );
  6. 宏代码片段由预处理器处理,进行简单的文本替换 ,没有任何编译过程,因此可能出现副作用。

如图2所示的代码,用情况1编译后的执行结果如图3所示;这就是宏代码出现的副作用,情况1的文本替换后如图 4所示:

图2

图3

图4

用图2代码的情况2编译执行后的结果如图5所示,这个就和分析的一样,因此内联函数不会产生副作用。

图5

    用图2代码的情况2在VS2015的默认编译后的汇编代码如图6所示;从图6中可以看到有函数的调用,说明inline的内联请求被拒绝了;这是因为编译器的优化功能没有被设置。编译器的优化功能设置如图7所示,经过设置了编译器的优化功能后,编译后的汇编代码如图8所示,从图8中可以到没有函数调用了,而是将函数体插入函数调用的地方。

图6

图7

图8

四、现代C++编译器对内联函数的优化

  1. 现代C++编译器能够进行编译优化 ,一些函数即使没有inline声明,也可能被内联编译。
  2. 一些现代C++编译器提供了扩展语法,能够对函数进行强制内联,如图9的代码和如下所示:
    1. g++:__attribute__((always_inline))属性
    2. MSVC:__forceinline

图9

五、C++中inline内联编译的限制

  1. 不能存在任何形式的循环语句;
  2. 不能存在过多的条件判断 语句;
  3. 函数体不能过于庞大;
  4. 不能对函数进行取地址操作;
  5. 函数内联声明必须在调用语句之前。

六、内联函数、宏和带参数函数三者的比较

内联函数的优点:函数代码被装入符号表中,在使用时进行替换没有调用开销,效率高,会进行参数类型检查。

内联函数的缺点:函数代码较长,使用内联将消耗过多内存;函数体内有循环,执行代码的时间比较长。

宏的优点:原地展开,没有调用开销;并且在预处理阶段完成,不占用编译时间。

宏的缺点:不进行类型检查,多次宏替换会导致代码体积变大;一些参数的副作用会导致得出错误的结果。

带参函数的优点:编译器会做参数的静态类型检查。

带参函数的缺点:需要传参、栈变量的开辟和销毁;压栈、跳转、返回开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

划清界限

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

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

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

打赏作者

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

抵扣说明:

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

余额充值