【C++】内联函数

举报
修修修也 发表于 2024/04/27 14:55:25 2024/04/27
【摘要】 为什么C++要引入内联函数?频繁消耗栈帧的函数栈帧的简单介绍:       当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分栈称为栈帧。下图描述了栈帧的通用结构。栈帧是一段有界限的内存区间,由最顶端的两个指针界定,寄存器%ebp为基址指针寄存器(extended base pointer),而寄存器%esp为栈指针寄存器(extended stack p...

为什么C++要引入内联函数?

频繁消耗栈帧的函数

栈帧的简单介绍:
       当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分栈称为栈帧。下图描述了栈帧的通用结构。栈帧是一段有界限的内存区间,由最顶端的两个指针界定,寄存器%ebp为基址指针寄存器(extended base pointer),而寄存器%esp为栈指针寄存器(extended stack pointer)(也就是说寄存器%ebp保存了所分配内存的最高地址,寄存器%esp保存了所分配内存的最低地址)。当程序执行时,栈指针(栈顶)可以移动,因此大多数信息的访问都是相对于桢指针的。

        也就是说,每当我们在C语言中调用函数时,栈上都需要开辟一定空间供我们使用,从汇编代码的角度来看,如果是重复进行大量的函数压栈操作,对于栈上空间的消耗是巨大的,极易导致栈溢出现象发生,进而导致程序崩溃,因此我们需要一些解决方法来防止这样的错误产生.


极易出错的宏替换

        在C语言中,为了解决类似的问题,我们学习了使用类函数宏来替换这些大量重复使用但又并不复杂的函数,如,将求两数中的最大值的函数改写为类函数宏:

#define X 3

#define Y 5

#define MAX(X,Y) X>Y?X:Y

int main()

{

    printf("%d", MAX(X, Y));

    return 0;

}


        但宏替换并不是一个很好的解决方案,因为它简单粗暴的替换逻辑非常容易导致出错,如:

        以及其他相关的问题,具体可以查看这篇博客的第四部分:宏定义陷阱,这里就不一一赘述了.【C语言】什么是宏定义?(#define详解)


内联函数的概念

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

        如下函数Max,只需要在正常函数前加上关键字inline就可以使其称为内联函数:

inline int Max(int x, int y)

{

    return x > y ? x : y;

}

int main()

{

    int max=Max(3, 5);

    return 0;

}


内联函数的特性

• inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

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

• inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。如:

• 注:默认debug版本下内联不会起作用,否则就无法调试了。


结语

希望这篇关于内联函数的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。