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

参考

相关推荐
T1mzhou9 小时前
ARM64 Linux 6.10内核启动流程7-ioremap和readl writel
linux·服务器·c语言
未来之窗软件服务14 小时前
计算机二级[英文]-C 字符串移动—东方仙盟
c语言·开发语言·仙盟创梦ide·东方仙盟
是隼人19 小时前
buuctf-pwn bypwn(ret2shellcode)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
T1mzhou20 小时前
ARM64 Linux 6.10内核启动流程6-psci.c和ATF/U-Boot 的电源接口
linux·服务器·c语言
是隼人20 小时前
buuctf-pwn PWN2(整数溢出)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
LuminousCPP21 小时前
数据结构 - 排序(二):快速排序从错误初版到优化版|双指针划分 + 三数取中 + 小区间插入优化
c语言·数据结构·笔记·算法·排序算法
竞赛考级题库21 小时前
202606 青少年等级考试C/C++真题一级 建议答题时长:60min
java·c语言·c++
迷茫、Peanut21 小时前
C语言混合链接
c语言
wdfk_prog1 天前
RT-Thread Kconfig 配置明明是 y,为什么 rtconfig.h 就是不生成?一次 `_PATH` 后缀踩坑复盘
c语言
是隼人1 天前
buuctf-pwn jarvisoj_level5(64位ret2libc)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门