C语言内联函数

在阅读代码的过程中,我们有时候会碰到使用 inline 修饰的函数。这是C99 新增的内联函数(inline function)。这种内联函数相当于给编译器一个建议,告诉它将函数的代码插入到调用的地方。编译器可以选择忽略内联函数的建议,继续将函数编译为常规函数。

简单的说,对于常规函数编译器会将它解释成压栈,然后 call 函数名这样的指令;对于内联函数,编译器可以直接在调用处“展开”。这样就避免了压栈和 call 的开销。这样的设计让人很容易联想起来宏定义。

以一个例子来进行说明:

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>

inline void swapINT1( UINTN *p1, UINTN *p2 )       // 一个内联函数
{
   UINTN tmp = *p1; *p1 = *p2; *p2 = tmp;
}

void swapINT2( UINTN *p1, UINTN *p2 )       // 一个内联函数
{
   UINTN tmp = *p1; *p1 = *p2; *p2 = tmp;
}

INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  UINTN a=12,b=34;
  swapINT1(&a,&b);
  swapINT2(&a,&b);

  return(0);
}

代码非常简单,定义了一个内联函数 swapINT1() 和一个普通函数swapINT2()。我们在编译种加入 /FAcs 让它生成汇编文件。

ShellAppMain PROC					; COMDAT

; 36   : {

$LN5:
  00000	48 89 54 24 10	 mov	 QWORD PTR [rsp+16], rdx
  00005	48 89 4c 24 08	 mov	 QWORD PTR [rsp+8], rcx
  0000a	48 83 ec 48	 sub	 rsp, 72			; 00000048H

; 37   :   UINTN a=12,b=34;

  0000e	48 c7 44 24 28
	0c 00 00 00	 mov	 QWORD PTR a$[rsp], 12
  00017	48 c7 44 24 20
	22 00 00 00	 mov	 QWORD PTR b$[rsp], 34	; 00000022H

; 14   :    UINTN tmp = *p1; *p1 = *p2; *p2 = tmp;

  00020	48 8b 44 24 28	 mov	 rax, QWORD PTR a$[rsp]
  00025	48 89 44 24 30	 mov	 QWORD PTR tmp$1[rsp], rax
  0002a	48 8b 44 24 20	 mov	 rax, QWORD PTR b$[rsp]
  0002f	48 89 44 24 28	 mov	 QWORD PTR a$[rsp], rax
  00034	48 8b 44 24 30	 mov	 rax, QWORD PTR tmp$1[rsp]
  00039	48 89 44 24 20	 mov	 QWORD PTR b$[rsp], rax

; 38   :   swapINT1(&a,&b);
; 39   :   swapINT2(&a,&b);

  0003e	48 8d 54 24 20	 lea	 rdx, QWORD PTR b$[rsp]
  00043	48 8d 4c 24 28	 lea	 rcx, QWORD PTR a$[rsp]
  00048	e8 00 00 00 00	 call	 swapINT2

; 40   : 
; 41   :   return(0);

  0004d	33 c0		 xor	 eax, eax

; 42   : }

  0004f	48 83 c4 48	 add	 rsp, 72			; 00000048H
  00053	c3		 ret	 0
ShellAppMain ENDP

从上面可以看到 swapINT1() 被“展开”了,swapINT2() 则是正常的通过 call 来调用的。

需要注意的是:内联函数对于编译器来说只是“建议”,编译器完全可以不接受这个建议。例如,r如果函数比较复杂,编译器不会遵从这个建议。

参考:

  1. https://www.cnblogs.com/zhuchunlin/p/17756920.html C语言 - 内联函数
  2. https://c.biancheng.net/view/339.html C语言内联函数