博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++深度解析 内联函数分析 内联inline和宏#define(5)
阅读量:1817 次
发布时间:2019-04-25

本文共 2176 字,大约阅读时间需要 7 分钟。

C++深度解析 内联函数分析(5)

 

 

 

#define

宏定义会经过预处理器,只是进行文本替换,缺点在于不会进行语法和语义检查的,仅仅是复制、粘贴的过程,编译器根本不知道宏的存在

所以,C++中,当需要某个类型的常量时,可以使用const常量 来代替 宏常数,如:

const int A = 3   <<<-------替代------->>> #define A 3

 

 

 

内联函数 inline

使用内联函数 替代 宏代码片段

使用inline关键字声明内联函数。

内联函数没有普通函数调用的时候的额外开销(参数的入栈,函数的返回,跳转)。

内联函数会被编译器优化,编译器直接将内联函数的函数体进行扩展,扩展到调用内联函数的地方

C++编译器不一定满足函数的内联请求

示例代码一:(宏)

#include 
//宏代码块#define FUNC(a, b) ((a) < (b) ? (a) : (b))inline int func(int a, int b){ return a < b ? a : b;}int main(int argc, char *argv[]){ int a = 1; int b = 3; //FUNC(++a, b)会被预处理器展开为:((++a) < (b) ? (++a) : (b)) int c = FUNC(++a, b); //((++a) < (b) ? (++a) : (b)); printf("a = %d\n", a); // 3 printf("b = %d\n", b); // 3 printf("c = %d\n", c); // 3 return 0;}

结果如下:

因为FUNC是一个宏定义,文本替换。比较时候++a:a=2。如果条件成立++a:a=3。(从而a被加了两次)由此看来,使用宏定义是有副作用的。

示例代码二:(内联函数)

#include 
#define FUNC(a, b) ((a) < (b) ? (a) : (b))inline int func(int a, int b){ return a < b ? a : b;}int main(int argc, char *argv[]){ int a = 1; int b = 3; int c = func(++a, b); printf("a = %d\n", a); // 2 printf("b = %d\n", b); // 3 printf("c = %d\n", c); // 2 return 0;}

结果如下:

内联函数直接将函数体插入到调用的地方示例中,int c = func(++a, b)调用了内联函数,所以把函数体直接扩展到func(++a, b)。

 

 

 

内联函数总结:

内联函数具有普通函数的特征(参数检查,返回类型等)

函数的内联请求可能被编译器拒绝(通过配置的方式,让编译器接受内联请求)

函数被内联编译后,函数体直接扩展到调用的地方。

(宏代码片段由预处理器处理,进行简单的文本替换,没有任何编译过程,因此可能出现副作用)

因此,在C++编程中,首选内联函数,而不是宏代码片段。

 

 

 

对函数进行强制内联

g++:__attribute__((always_inline))属性,当一个函数拥有这个属性后,这个函数就会被g++编译器强制内联

MSVC:__forceinline

示例代码一:

#include 
//__forceinline //MSVC__attribute__((always_inline)) // g++//inlineint add_inline(int n);int main(int argc, char* argv[]){ int r = add_inline(10); printf("r = %d\n", r); return 0;}inline int add_inline(int n){ int ret = 0; for(int i = 0; i < n; i++) { ret += i; } return ret;}

 

 

 

注意:C++中inline内联编译的限制:

总的来说,函数体不能过于复杂。

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

内联函数和普通函数的区别:

  • 普通函数:每次调用前,CPU都会保存现场(入栈),调用完后还要恢复现场(出栈)等额外开销。
  • 内联函数:就会在每次调用的地方,将内联函数里的代码段“内联地”展开,所以省去了额外的开销

 

 

 

小结:

C++中可以通过inline声明内联函数

编译器直接将内联函数扩展到函数调用的地方

inline只是一种请求,编译器不一定允许这种请求

内联函数省去了函数调用时压栈跳转返回的开销

 

 

转载地址:http://pmwkf.baihongyu.com/

你可能感兴趣的文章
Mac Charles 替换和改写接口地址、环境、参数、状态码等
查看>>
高并发解决思路
查看>>
单片机实验四:定时器控制发光二极管的亮灭+简单输出连续矩形脉冲
查看>>
微机接口实验一:七段数码管循环动态显示00~99
查看>>
微机接口实验二:键盘显示控制实验(翻转法实现)
查看>>
微机接口实验三:交通灯控制实验(C口置位/复位控制字的使用)
查看>>
微机接口实验四:可编程定时器/计数器8254
查看>>
浮点加减运算中关于结果规格化的思考
查看>>
流水线中数据相关的理解(RAW、WAR和WAW)
查看>>
基于安卓界面的编译原理课程设计:C语言的预处理程序
查看>>
Chaquopy给AS添加Python环境时提示:No Python interpreter configured for the module
查看>>
解决Chaquopy在AS中pip安装过慢的问题
查看>>
Chaquopy在AS中pip时报错error: CCompiler.compile: Chaquopy cannot compile native code
查看>>
Chaquopy读取Android项目python目录下的文件
查看>>
DL入门(1):卷积神经网络(CNN)
查看>>
DL入门(2):自编码器(AutoEncoder)
查看>>
DL入门(3):循环神经网络(RNN)
查看>>
DL入门(4):长短期记忆网络(LSTM)
查看>>
dataframe在最左边添加一列索引
查看>>
深度学习方法在负荷预测中的应用综述(论文阅读)
查看>>