我读到动态链接指向上一个激活记录,因此在动态范围编程语言中是有意义的。但是在静态范围编程语言中,为什么访问链接(指向一个较低嵌套级别的功能的激活记录)是不够的? 特别是在C中 - 为什么不需要访问链接?为什么需要动态链接?
答案 0 :(得分:4)
我将使用这个对我来说比较熟悉的命名法:
激活记录:堆叠框架
动态链接:[已保存]帧指针
所以,我将你的问题解释为:为什么需要帧指针? [1]
帧指针不是必需的。
有些编译器(例如Green Hills C ++,带-O2的GCC)通常不会生成一个或者可能被要求不生成它(MSVC,GCC)。
那就是说,它当然有它的好处:
轻松遍历call stack :生成stack trace就像遍历框架指针构成头部的链接列表一样简单。使实现堆栈跟踪和调试器变得更加容易。
更容易生成代码:可以通过索引帧指针而不是随时更改堆栈指针来引用堆栈变量。堆栈指针随每次按下/弹出而变化,帧指针在函数内保持不变(在prologue/epilogue之间)
如果出现问题,可以使用帧指针完成 stack unwinding 。这就是Borland的结构化异常处理(SEH)的工作原理。
缺点:
但正如您所注意到的,编译器可以生成完美的代码而无需维护帧指针。
[1]如果这不是什么意思,请详细说明。
答案 1 :(得分:2)
您的问题可能与optimizing option的-fomit-frame-pointer
GCC有关,请参阅this。
动态链接实际上仅对nested函数(可能是closures)有用,而标准C没有它们。有些人会谈到 display 链接。标准C没有嵌套函数,所以不需要任何相关技巧(显示链接,蹦床......)。
GCC编译器提供nested functions作为 C语言扩展,并使用激活记录上的动态链接实现它们,非常接近您的想法。另请阅读man or boy test和trampoline上的wikipages。