说说C语言内联函数

前言

因为函数一般具有参数传递过程,则就会存在压栈、出栈、指令跳转等操作,所以,会多一些指令的消耗。

但是,此处并非不建议多封装函数,反而是非常推荐多封装函数,提高封装和内聚性。

后期利用编译器的自主优化能力,就可以轻松带来程序性能的提升。

仅建议在适合的地方,用内联函数

结论先行

  • c语言中,内联函数最好的实现方式: 在头文件中提供static inline的函数声明和短小代码实现
c 复制代码
static inline int foo(int t) 
{ 
  return ++t;
}

编译器内联重点选项

  • -finline-functions-called-once
  • -finline-small-functions
  • -finline-functions

为什么建议多封装函数,而非是反其道而行,封装函数是为了人类更好地理解和维护,但对于机器而言,其实不是必须的!

编译器在自主优化的时间,对于小函数、仅调用一次的静态函数、和其他认为可以的函数都会尝试内联。

对于GCC而言,轻松开启-O[n]的优化措施,就会导致这些内联行为的方式!

一些怪异的内联现象

我们知道无论在c/c++中,inline仅是建议编译器进行内联的声明,而在编译后,是否采取了内联,则取决于比较多的因素:

  • 代码自身长度、复杂度(甚至包括递归、跳转等难以内联的存在)
  • 编译器优化级别
  • 是否跨编译模块链接

按照个人对于内联的理解,即使是编译器指示信息__attribute__((always_inline)) ,仅是告诉编译器在没有优化选项的时间,也要尝试内联,而非一定要内联,具有强迫的超能力

对跨编译模块内联

我们知道编译器是针对源文件产生目标文件,然后,再对各个目标文件链接,成为共享库或可运行程序。

所以,内联函数在源文件中定义实现,通常会出现链接问题。

相对来说,最简单的内联函数方法,实现方式就是在头文件,既提供声明,又提供定义实现!

另外,由于头文件一般不会过大,同时,维护头文件的自觉,也会约束内联函数不能过长 😃

编外语: 猜测内联规范并非强制,而且在头文件中可以轻松避免问题,所以,GCC编译器对于跨编译模块的内联,并不上心。你可以认为它是特性,或者是bug

其它一些值得考虑的手段

  • c++中模版函数更可以成为另一种选择
  • 次选宏的替代(除了函数在引用地方能够直接终结函数流程和泛型的场景,其它内联函数均可提供平替,而且具有类型安全)

参考

相关推荐
老猿讲编程2 小时前
安全C语言编码规范概述
c语言·开发语言·安全
fai厅的秃头姐!8 小时前
C语言03
c语言·数据结构·算法
life_time_8 小时前
C语言(22)
c语言·开发语言
鱼嘻10 小时前
Linux自学day23-进程和线程
linux·服务器·c语言·进程和线程
BUG 劝退师11 小时前
C语言预处理学习笔记
c语言·笔记·学习
小立爱学习12 小时前
Linux 内核自旋锁spinlock(四)--- queued spinlock
linux·c语言
我爱蛋蛋后14 小时前
Linux驱动开发之音频驱动与基础应用编程
linux·c语言·驱动开发·音视频
卷卷的小趴菜学编程15 小时前
c++之多态
c语言·开发语言·c++·面试·visual studio code
大白的编程日记.16 小时前
【C++笔记】C+11深度剖析(三)
c语言·开发语言·c++
和光同尘@17 小时前
56. 合并区间 (LeetCode 热题 100)
c语言·开发语言·数据结构·c++·算法·leetcode·职场和发展