🫒内联函数和constexpr函数
2022-5-10
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

内联函数

C语言觉得一个小函数重复调用函数栈帧,函数栈帧中保存一些寄存器,之后又销毁,这些都是有消耗的,所以C语言引入#define宏
 
宏的优点:增强代码复用性,提高性能
缺点:
  • 不方便调试(预编译阶段进行替换,调试的时候看不到)
  • 代码可读性差,维护差,容易误用
  • 没有类型的检查(单纯替换不会报错,但是错误)
 
C++替代宏的方法:
  • const修饰的函数(const成员函数)
  • 内联函数
 
内联函数是 C++ 为了改进 C 中类函数宏所作出的努力,内联函数具有闭合子程序的所有特性,然而编译器会将函数调用过程展开为执行代码。优雅地融合了函数和宏的特性。好处在于:更加容易阅读和理解程序意图、行为统一、易于修改和重用,展开执行代码将减轻了函数调用的额外工作:保存寄存器并恢复、赋值参数、程序跳转。
由于内联函数将在每一处调用时进行展开,所以,要求要函数将是非常小的,不然生成的执行文件将很大,如果函数是递归的更是不应该内联。而且由于内联展开发生在编译期间,所以,应当将内联函数代码放在头文件中,才能在编译其它文件时进行展开,原因是编译器必须看到执行的代码才能展开。内联函数通常是给编译器的一种提示,编译器会根据实际情况内联或者忽略。
 
定义内联函数时需要在函数的返回类型前添加关键字 inline:
 
在函数声明和定义中都能使用关键字inline,但是建议只在函数定义时使用
 
编译时C++编译器会在调用内联函数的地方展开,是没有函数压栈的开销的。
如果不展开,假设有1000个调用,编译后台就会有10+1000条指令;如果展开,编译后台合计会有 10 * 1000 条指令,这是一场以空间换取时间的交易。因为没有了函数压栈的开销,所以能提高程序运行的效率。
 
  • inline空间换时间,省去调用函数栈帧开销。适用于优化规模较小、流程直接、调用频繁的函数。所以代码很长、循环或递归的函数不适宜成为内联函数。
  • 对于inline编译器会自动优化,是否是内联函数不是自己决定的。如果定义为inline的函数体内有循环/递归等,编译器优化时会忽略掉内联,会被编译为普通函数。
  • inline声明和定义不建议分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
 

constexpr函数

constexpr函数指的是在编译的时候就能得到其返回值的函数,也就是说编译器将constexpr函数直接转换成其返回值,因此,constexpr函数都是被隐式地定义为内联函数。使用constexpr关键字来修饰constexpr函数。
constexpr函数能用于常量表达式的函数。constexpr 函数的返回类型及所有形参的类型都得是字面值类型。另外C++11标准要求constexpr函数体中必须有且只有一条 return 语句,但此限制在C++14中删除。
 
constexpr函数的返回值可以不是一个常量:
scale 的实参是常量表达式时,它的返回值也是常量表达式,反之则不然:
注:constexpr 函数不一定返回常量表达式。
 
 
和其他函数不同,内联函数和 constexpr 函数可以在程序中多次定义。因为在编译过程中,编译器需要函数的定义来随时展开函数,仅有函数的声明是不够的。对于某个给定的内联函数或 constexpr 函数,它的多个定义必须完全一致。因此内联函数和 constexpr 函数通常定义在头文件中。
 
  • C++
  • 函数重载和匹配函数指针
    目录