记录一下inline函数的作用

普通函数的调用过程

在eclipse里面创建工程,代码如下:

#include <iostream>
#include <vector>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;//__attribute__((always_inline)) inline int test(int x)
int test(int x)
{return x++;
}int main()
{int i = 0;int y = 0;for (i = 0; i < 9; i++)y = test(i);}

上述例子,test为普通函数,单步执行时的汇编代码如下所示:

                  main():
0000000000401550:   push    %rbp
0000000000401551:   mov     %rsp,%rbp
0000000000401554:   sub     $0x30,%rsp
0000000000401558:   callq   0x4016d0 <__main>
24                  int i = 0;
000000000040155d:   movl    $0x0,-0x4(%rbp)
25                  int y = 0;
0000000000401564:   movl    $0x0,-0x8(%rbp)
27                  for (i = 0; i < 9; i++)
000000000040156b:   movl    $0x0,-0x4(%rbp)
0000000000401572:   cmpl    $0x8,-0x4(%rbp)
0000000000401576:   jg      0x40158b <main()+59>
28                      y = test(i);
0000000000401578:   mov     -0x4(%rbp),%eax
000000000040157b:   mov     %eax,%ecx
000000000040157d:   callq   0x402cc0 <test(int)>
0000000000401582:   mov     %eax,-0x8(%rbp)
27                  for (i = 0; i < 9; i++)
0000000000401585:   addl    $0x1,-0x4(%rbp)
0000000000401589:   jmp     0x401572 <main()+34>
30                }
000000000040158b:   mov     $0x0,%eax
0000000000401590:   add     $0x30,%rsp
0000000000401594:   pop     %rbp
0000000000401595:   retq test(int):
0000000000402cc0:   push    %rbp
0000000000402cc1:   mov     %rsp,%rbp
0000000000402cc4:   mov     %ecx,0x10(%rbp)
19                  return x++;
0000000000402cc7:   mov     0x10(%rbp),%eax
0000000000402cca:   lea     0x1(%rax),%edx
0000000000402ccd:   mov     %edx,0x10(%rbp)
20                }
0000000000402cd0:   pop     %rbp
0000000000402cd1:   retq

可以看到,main函数会调用callq 402cc0去执行test函数,执行test函数时,有完整的入栈、出栈、return过程。

inline函数的调用过程
将上述代码中test函数更改如下,起初没有加__attribute__((always_inline)),由于编译选项(-O0)和单步调试的原因,inline一直没有生效,所以强制加上__attribute__((always_inline))。

__attribute__((always_inline)) inline int test(int x)
//int test(int x)
{return x++;
}

具体的汇编代码执行过程如下:

                  main():
0000000000401550:   push    %rbp
0000000000401551:   mov     %rsp,%rbp
0000000000401554:   sub     $0x30,%rsp
0000000000401558:   callq   0x4016d0 <__main>
24                  int i = 0;
000000000040155d:   movl    $0x0,-0x4(%rbp)
25                  int y = 0;
0000000000401564:   movl    $0x0,-0x8(%rbp)
27                  for (i = 0; i < 9; i++)
000000000040156b:   movl    $0x0,-0x4(%rbp)
0000000000401572:   cmpl    $0x8,-0x4(%rbp)
0000000000401576:   jg      0x401590 <main()+64>
0000000000401578:   mov     -0x4(%rbp),%eax
000000000040157b:   mov     %eax,-0xc(%rbp)
19                  return x++;
000000000040157e:   mov     -0xc(%rbp),%eax
0000000000401581:   lea     0x1(%rax),%edx
0000000000401584:   mov     %edx,-0xc(%rbp)
28                      y = test(i);
0000000000401587:   mov     %eax,-0x8(%rbp)
27                  for (i = 0; i < 9; i++)
000000000040158a:   addl    $0x1,-0x4(%rbp)
000000000040158e:   jmp     0x401572 <main()+34>
30                }
0000000000401590:   mov     $0x0,%eax
0000000000401595:   add     $0x30,%rsp
0000000000401599:   pop     %rbp
000000000040159a:   retq

可以看到,直接将test函数的return x++; 三条指令插到了main函数中,不用再去压栈、执行、出栈那样操作。从代码执行效率上来讲,后面这种方式是明显优于普通函数的执行方式的。

总结:

  • inline函数调用时,不需要繁琐的入栈、出栈过程,这一点相对于普通函数执行效率会高很多;
  • inline函数在编译时,会将函数体直接插入到调用点,这样函数的调用更加简单,但是如果调用点多的话,会增加代码体积;
  • 相比于宏,inline函数是函数,可以单步调试,宏是在预编译过程中直接替换文本;
  • 虽说inline函数执行时效率高,但是不能把所有的函数都写成inline函数,一般inline函数里面不能有循环语句,一般是把频繁调用且精简的代码写成inline函数。

c语言中inline函数的作用相关推荐

  1. c语言中fputc函数的作用是,C语言中fputc函数的用法

    C语言中fputc函数的用法 C语言中fputc函数的用法为"int fgetc (FILE *fp)",该函数的作用是从指定的文件中读取一个字符, 读取成功时会返回读取到的字符, ...

  2. c语言中fputc函数的作用是,C语言中fputc函数的用法_后端开发

    Python画ROC曲线和AUC值计算(附代码)_后端开发 ROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器的优劣.这篇文章将先简单的 ...

  3. c语言中sizeof函数的作用是,c语言中sizeof函数的用法

    C语言sizeof函数如何使用? 怎样利用sizeofCSS布局HTML小编今天和大家分享各种数据类型占用的字节数? (1)sizeof不是函数,它只是一个操作符(operator). (2)size ...

  4. 在c语言中log函数的作用,C语言中log函数怎么使用啊

    优质回答 回答者:奔跑的五花肉11 1.C语言中,有两个log函数,分别为log10和log函数,具体用法如下: 2.函数名: log10 功 能: 对数函数log,以10为底 用 法: double ...

  5. c语言中strcat函数的作用,strcat函数的作用是什么?

    strcat函数的作用是复制一个字符串,将这个字符串拼接在另一个字符串后面.strcat()函数接受两个字符串作为参数,会把第二个字符串的备份附加在第一个字符串末尾,并把拼接后形成的新字符串作为第一个 ...

  6. c语言说明函数的作用是,C语言中rewind函数的作用是什么?

    rewind函数的作用是:使文件位置指针重新返回文件的开始位置. C语言rewind函数 rewind函数是C语言程序中的库函数 功 能:将文件内部的位置指针重新指向一个流(数据流/文件)的开头 注意 ...

  7. c语言程序功能作用是什么,C语言中rewind函数的作用是什么?

    rewind函数的作用是:使文件位置指针重新返回文件的开始位置. C语言rewind函数 rewind函数是C语言程序中的库函数 功 能:将文件内部的位置指针重新指向一个流(数据流/文件)的开头 注意 ...

  8. c语言中fputc函数的作用是,C语言中文件的读写函数之 fputc、fgetc

    C语言中文件的读写函数之 fputc.fgetc 首先,我们要知道fputs和fgetc这两个函数是包含在标准库函数中的函数,换句话说,就是封装在标准函数中的两个函数.其中这两个函数都是每次只能输入或 ...

  9. 在c语言中log函数的作用,C++_在C语言中使用对数函数的方法,C语言log()函数:返回以e为底的 - phpStudy...

    在C语言中使用对数函数的方法 C语言log()函数:返回以e为底的对数值头文件: #include log() 函数返回以 e 为底的对数值,其原型为: double log (double x); ...

最新文章

  1. Django博客系统工程创建和配置
  2. Android RSA加密对象数据
  3. LCD 显示异常定位分析方法
  4. 关于金蝶k3 wise供应生门户登陆界面屏蔽业务账套多余功能模块设置方法
  5. Python 初学者必看:Python 异常处理集合
  6. android 显示字符串最后一个字,android – 在textview中显示的最后一个单词
  7. 解决:Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRA
  8. python编程能有什么用_python编程能做什么开发
  9. pycharm中两个.py文件相互调用和传递参数
  10. 整理搜集iOS不同版本间的介绍
  11. 8月份的To-Do List
  12. Android内存、性能是程序永恒的话题
  13. visual studio code安装
  14. 投影幕布尺寸计算器_投影距离计算器
  15. Linux(一)之Ubuntu上安装nginx、nginx-rtmp-modeule、libx264、FFmpeg(巨详细)
  16. matlab单枝节匹配器,第八讲微带匹配电路单枝节匹配电路.ppt
  17. Unity3D游戏启动界面常用设置
  18. ppt文件怎么压缩,ppt压缩的办法步骤
  19. Fleck webSocket
  20. 时钟页面置换算法c语言,clock置换算法例题(改进clock置换算法例题讲解)

热门文章

  1. 作为一名83岁的长者,我开发了一款游戏App
  2. c#中设置EXCEL的行高或者是列宽
  3. 2018最值得期待:全能型PaaS厂商灵雀云
  4. 你知道什么时候用@PostMapping和@GetMapping吗?
  5. 实训十六:路由器RIPV2配置
  6. 冬至,这一天,与汤圆饺子一样暖心的——还有我呢
  7. Ajax onreadystatechange事件
  8. JavaEE 网络编程示例1 UDP套接字数据报编程 == 一发一收
  9. 无CUDA支持的dlib库的安装与使用
  10. Day 32 淘宝网店+斐波那契凤尾