语法:
函数前面加inline,如:
inline int sum(int x ,int y)
{ }
要点:
1、inline内联函数 和 普通函数的区别:
若是inline内联函数,在编译过程中,就没有函数的调用开销了,在函数的调用点直接把函数的代码进行展开处理了
2、inline函数不再生成相应的函数符号
3、inline只是建议编译器把这个函数处理成内联函数,但是不是所有的inline都会被编译器处理成内联函数----如:递归、函数内容比较多的
4、debug版本上,inline是不起作用的;inline只有在release版本下才能出现
补充,函数的调用过程:
int sum(int a ,int b)
{
int temp=a+b;
return temp;
}
int main()
{
int x=3;
int y=5;
int ret=sum(x ,y);
return 0;
}
二、汇编代码分步解析(x86架构)
1. 调用前:参数压栈(从右向左)
; main函数中调用 sum(a, b) 的汇编代码
push y ; 第二个参数压栈(b=5)
push a ; 第一个参数压栈(a=3)
call add ; 调用函数,返回地址压栈
add esp, 8 ; 调用者清理栈空间(cdecl约定)
2. 进入被调函数:保存栈帧
add:
; 保存调用者的栈帧基址
push ebp ; 旧ebp压栈
mov ebp, esp ; 新ebp指向当前栈顶
; 分配局部变量空间(假设需要4字节)
sub esp, 4 ; esp下移,预留result的空间
3. 执行函数逻辑
; 通过ebp访问参数和局部变量
mov eax, [ebp+8] ; 取第一个参数a(a=3)
add eax, [ebp+12] ; 加第二个参数b(b=5)
mov [ebp-4], eax ; 结果存入局部变量result
; 返回值放入eax
mov eax, [ebp-4] ; eax = 8
4. 恢复栈帧并返回
; 释放局部变量空间
mov esp, ebp ; esp回到ebp位置(回收栈空间)
; 恢复调用者的ebp
pop ebp ; 弹出旧ebp到寄存器
; 返回调用者(ret弹出返回地址到eip)
ret
三、内存布局图示(调用过程中栈的变化)
调用 sum(x, y)
前的栈:
高地址
| ... |
| y=5 | ← [ebp+12] (第二个参数)
| x=3 | ← [ebp+8] (第一个参数)
| 返回地址 | ← esp 在此处(call指令压入)
低地址
进入 add
函数后的栈:
高地址
| ... |
| y=5 | ← [ebp+12]
| x=3 | ← [ebp+8]
| 返回地址 |
| 旧ebp | ← ebp 现在指向这里
| result | ← [ebp-4] (局部变量)
低地址 ← esp 现在指向这里