C/C++中内联函数与静态函数

时间:2021-09-10 01:01:27

C++中的内联函数与静态函数

静态函数

静态函数的定义

静态函数又称为内部函数。在C/C++中,定义的函数默认都是全局的(相对于多个文件的源程序)。而在函数的前面加上static关键字可以改变函数的作用域,即将函数的作用域限定在含有此函数的定义所在的文件,在其他文件中不可以使用此函数。

static void fun() {
printf("this is in the static function\n");
}

静态函数的作用

静态函数有两个作用:

  • 起隐藏作用,静态函数只能在本文件中被访问,而不能被除此文件外的其他文件所使用。
  • 使用静态函数可以在其他文件中定义同名的函数,而不用考虑会出现名字冲突或者冲定义的错误。

静态函数的内存分配

static只会改变(限制)函数的作用域,而不会像静态变量那样改变变量的存储位置。static的函数和普通函数的内存存储区域以及内存分配方式是相同的。

内联函数(GCC)

内联函数的定义

GCC中的inline函数可以相当于在一个普通的全局函数加上inline属性。inline关键字仅仅是建议编译器在编译的时候做内联展开处理,而不是强制在gcc编译器中,如果吧编译选项设置为负无穷,即使是inline函数也不会被内联展开,除非设置了强制内联展开的属性(attribute((always_inline)))。

static inline

GCC中static inline定义比较容易理解:可以将其看做是在static函数前面加上了inline属性.这个函数的大部分属性和static函数一样,只不过在调用这个函数的时候,gcc会在其调用处将其汇编代码展开编译而不为这个函数生成独立的汇编代码。除了以下情况外:

(1)函数的地址被使用时,如果通过函数指针对函数进行了间接调用的时候,这种情况下就不得不为static inline函数生成独立的汇编码,否则它没有自己的地址
(2)其他一些无法展开的情况,比如函数本身有递归调用自己的情况。

static inline函数和static函数一样,其定义的范围是local的,即可以在同一个程序的不同的文件中由同名的函数定义。
注意gcc中的static inline函数和C99中的static inline函数的用法是一致的,不用担心兼容问题
重点:

  • gcc的static inline相对于static函数来说只是在调用时建议编译器内联展开;
  • gcc不会特意未static inline函数生成独立的汇编代码,除非出现了非生成不可的情况。
  • gcc的static inline函数仅能作用于文件范围内。

inline

gcc中的inline函数也想对容易理解,相当于在一个普通的全局函数的前面加上了一个inline关键字。在它定义所在的文件内,它的表现和static inline的表现一致:再能展开的时候被内联展开编译。但是为了能够在文件外面调用它,gcc一定会为它生成一份独立的汇编代码,以便在文件外部进行调用
C/C++中内联函数与静态函数
重点:

  • gcc的inline函数相对于普通的extern函数的区别在于,当同一文件中调用的时候inline是建议进行内联展开,而extern不会
  • gcc一定会为inline函数生成一份独立的汇编代码,以便在本文件之外的其他文件调用,而static inline可能不需要
  • C的inline函数是全局性的:在文件内可以作为一个内联函数被展开,而在文件外可以被调用

extern inline

一个extern inline 函数只会被内联进去,而据对不会声称独立的汇编代码,即使是通过指针引用或者递归调用,也不会生成独立的汇编代码。另外extern inline函数允许和外部函数重名,即在一个同名的extern inline函数存在的情况下,再定义一个相同名字的全局函数,不会产生冲突。
C/C++中内联函数与静态函数
在这个文件中gcc不会生成foo函数的汇编码。在func1中的调用点①,编译器会*市nga面的foo函数的汇编代码内联到func1中的,而在②处,引用了foo的地址。但是编译器绝对不会为extern inline函数生成独立的汇编代码,所以这时候编译器将其处理为外部引用,当外部没有这个函数的时候,会出现未定义的错误。
重点:
- gcc绝对不会为extern inline的函数生成独立的汇编代码
- extern inline函数允许和全局函数重名,可以在文件范围内替代外部定义的全局函数
- extern inline函数的应用比较狭窄,行为奇怪,不建议使用