下面的文章我将会从三个方面去讨论liline这个关键字1.什么是inline,2.怎么用inline,3.inline有什么用?
学习inline就不可避免要了解一个c中的内容,宏定义,而inline就是在宏的基础做了改进的一个关键字。
#define 宏名 XXX 这是宏变量
#define 宏名(xx) xxx这是宏函数
在c中我们知道,在编译的时候会发生宏替换,就是在编译预处理的时候,编译器会把,代码中有宏的地方全部用宏定义的内容给替换掉,所以在运行的时候就已经没有了某个宏了,都已经替换掉了 。
使用宏函数是不需要额外开销的而使用一般的函数需要额外开销 比如(形参内存,现场保护,现场恢复..)调用一次函数需要将函数压栈,会创建一个栈帧。而使用宏就可以避免掉调用函数所需要的额外开销,如果是一个几十行上百行代码的函数那么创建栈帧的资源可以忽略不记,但是只有短短几行的代码那么这个资源就不可以忽略了所以宏可以使得效率得到了提升。
接下来就引入内联函数。
1.inline是什么?
c++中类似于宏定义的用法的一个关键字,修饰在函数返回值前面。
inline void func(int a);
和宏函数类似,是在编译的时候,将函数名用函数里面的内容进行替换
这样做可以不需要进行函数压栈操作,不需要额外的资源来进行函数调用。本质上是
一种用空间换时间的作用。省去了调用函数和建立栈帧的开销
2.inline怎么用?
语法 inline 返回值类型 函数名 (参数列表);
注意://不建议声明和定义分开因为 编译器遇到声明会认为之前的内联已经展开了,没必要将你的函数地址加入到符号表中,那么符号表中就没有这个函数名了,而你在调用的时候又是去符号表中去找这个函数,那么在符号表中就一定找不到函数的地址。就会报链接错误。
#include <iostream>
using namespace std; inline void f(int i);
void f(int i)
{
cout << i << endl;
}
在编译过程中,编译器一看,这里的 f() 是个inline,
inline就是说,“我”在调用的地方已经展开了,那么还需要这个给函数一个地址吗?不需要。
也就说F.cpp生成的符号表中,不会有f()的地址。
然后一链接,main.cpp中的 f(10); 就要去F文件给过来的符号表找 f() 的地址,找不到就会报链接错误。
————————————————
版权声明:本文为CSDN博主「Massachusetts_11」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yue152152/article/details/124761293
但是不要以为用了inline关键字编译器就一定会将你写的内联函数在编译时就展开了
具体看编译器怎么处理,如果你的函数是个递归或者函数很长的话编译器就不会将你内联进去
3.inline有什么用?
如上我们知道了inline的作用,心中有了疑惑,宏的功能不是跟他一样吗?为什么还要用
个内联不是多此一举了吗?
其实宏虽然功能和他一样但是不是很严谨会产生很多问题,c++开发者也考虑到了这点这才弄了个内联函数。
1.宏只要写了就一定能替换,而内敛函数则不同它只是对编译器的一个建议(成员函数都是内联函数)。
2.二者替换的时间不同,宏在编译预处理的时候进行宏替换,内联在编译阶段进行内联处理
3.宏替换不可调试,内联在部分编译器中是可以处理的
4.宏用的时候由于是完全的文本替换会造成很多的错误 比如最简单加法宏 如果不打几个括号都会出现很大的错误
5.内联函数可以读取私有属性数据,宏替换却不行