C++深度解析 内联函数分析 内联inline和宏#define(5)
发布日期:2021-06-28 16:05:18 浏览次数:2 分类:技术文章

本文共 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只是一种请求,编译器不一定允许这种请求

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

 

 

转载地址:https://blog.csdn.net/xiaodingqq/article/details/85014210 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C++深度解析 函数参数的扩展---函数参数的默认值,函数默认参数的规则,函数占位参数(6)
下一篇:C++深度解析 引用的本质分析 &(4)

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月28日 05时08分10秒