c语言中的函数嵌套

一 概要

C语言标准c89和c99中并不支持函数嵌套功能,它是GUN C的一个拓展,所以在gcc中是可以支持函数嵌套的,gcc对嵌套函数的说明如下:

https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html


二 实现

gcc主要通过Trampoline实现函数嵌套功能,那么什么是Trampoline呢?

Trampoline其实就是一段存在于栈上的可执行代码,它由运行时动态生成,通过运行栈上的这段代码跳转到真正的目的代码处。

至于函数嵌套为何要通过Trampoline去实现,这还得从嵌套函数的特点说起,因为它能够访问容器函数中的局部变量:

bar (int *array, int offset, int size)
{
  int access (int *array, int index)
    { return array[index + offset]; }
  int i;
  /*  */
  for (i = 0; i < size; i++)
    /*  */ access (array, i) /*  */
}
其中offset就是容器函数中的变量,可以在嵌套函数中直接引用,这看起来似乎不难实现:通过sp+offset即可轻松访问容器函数的栈变量,但还有一种情况必须要考虑,那就是嵌套函数不仅仅可以在容器函数中直接调用,还可能通过函数指针在其他函数中间接调用,这时活动栈帧布局跟容器函数就不一样了,通过sp+offset访问到的不再是容器函数中的对应变量位置了,这样就会得到意想不到的结果。

Trampoline可以有效的避免这种情况,因为Trampoline存在于容器函数的栈上,相对于要访问的容器函数的变量相对位置是固定的,所以不管怎么调用嵌套函数,执行的都是栈上的Trampoline,这样访问到的容器函数的变量位置总是正确的。不过这要求在嵌套函数调用时容器函数不能退出,否则栈上的Trampoline可能会被覆盖,同样会得到意想不到的结果。


三 优缺点

优点:函数调用时不用传递大量的参数;

缺点:代码移植性差,因为只有gcc支持,另外这要求栈是可执行的,不满足安全需求;


四 补充说明

如果嵌套函数中不引用容器函数中的任何变量,那么嵌套函数会被提升为普通函数,通过上面原理的分析,这点应该很好理解。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值