C++ · 入门 · 05 | 内联函数

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


前言

  • 以inline修饰的函数叫做内联函数编译时C++编译器会在调用内联函数的地方展开没有函数调用建立栈帧的开销内联函数提升程序运行的效率

一、概念

在这里插入图片描述

  • 如果在上述函数前增加inline关键字将其改成内联函数在编译期间编译器会用函数体替换函数的调用
  • 查看方式
    1. 在release模式下查看编译器生成的汇编代码中是否存在call Add
    2. 在debug模式下需要对编译器进行设置否则不会展开(因为debug模式下编译器默认不会对代码进行优化以下给出vs2019的设置方式)
      在这里插入图片描述
      在这里插入图片描述

二、特性

  1. inline是一种以空间换时间的做法如果编译器将函数当成内联函数处理在编译阶段会用函数体替换函数调用缺陷可能会使目标文件变大优势少了调用开销提高程序运行效率
  2. inline对于编译器而言只是一个建议不同编译器关于inline实现机制可能不同一般建议将函数规模较小(即函数不是很长具体没有准确的说法取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰否则编译器会忽略inline特性。下图为《C++prime》第五版关于inline的建议
    在这里插入图片描述
  3. inline不建议声明和定义分离分离会导致链接错误。因为inline被展开就没有函数地址了链接就会找不到

三、尽量以constenuminline替换#define

  • 这是博主在《Effective C++》看到的一个条款在此简化表述以下希望对铁汁们有帮助

3.1 宏的缺陷

  1. 宏没有类型安全检查
  2. 宏的可读性较差特别是所谓的宏函数
#define Add(x,y) ((x)+(y))

以上宏函数定义很容易招来许多错误比如
(1)缺少外面的括号

#define Add(x,y) (x)+(y)

在这种场景下就会出错

int main()
{
	Add(x,y)*2;//宏替换后=>x+y*2
	return 0;
}

(2)缺少里面的括号

#define Add(x,y) (x+y)

在这种场景下就会出错

int main()
{
	Add(a&b,a|b);//宏替换后=>a&b+a|b+优先级比&和|要高
	return 0;
}
  1. 宏无法调试在预处理期间就会被替换。比如你用了别人的头文件其中有#define NUM 10记号NUM从未被编译器看见当你遇到错误信息的时候提到10这个数你会一脸懵逼不知道从何而来造成麻烦

3.2 解决方案

  1. const替换宏常量
const int num = 10;
  1. enum替换宏常量
enum
{
	NUM = 10
}
  1. inline替换宏函数
    因为宏函数的优势就是直接展开了函数内容省去了栈帧开销而inline完全能够替代而且inline修饰的函数的的确确是个函数可以调试

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++