你自己已经解释过了。 “返回地址”的定义告诉你你下一步要去哪里.
不要求放入堆栈的返回地址是方法内部的地址called你现在使用的方法。它通常是的,这确实使调试变得更容易。但没有一个要求返回地址是调用者内部的地址。优化器被允许——有时确实——修改返回地址,如果这样做可以使程序更快(或更小,或者无论它优化的目的是什么)而不改变其含义。
堆栈的目的是确保当该子例程完成时,它是延续——接下来发生的事情——是正确的。堆栈的目的不是告诉你你从哪里来。它通常这样做是一个令人高兴的意外。
此外:堆栈只是概念的实现细节延续 and 激活。不要求这两个概念由同一个堆栈实现;可能有两个堆栈,一个用于激活(局部变量),一个用于继续(返回地址)。这种架构显然更能抵抗恶意软件的堆栈粉碎攻击,因为返回地址远离数据。
更有趣的是,根本不需要有任何堆栈!我们使用调用堆栈来实现延续,因为它们对于我们通常执行的编程类型:基于子例程的同步调用很方便。我们可以选择将 C# 实现为“Continuation Passing Style”语言,其中延续实际上是reified http://blogs.msdn.com/b/ericlippert/archive/2009/04/17/five-dollar-words-for-programmers-part-five-reification.aspx as an 堆上的对象,不作为一堆字节压入一百万字节的系统堆栈。然后该对象从一个方法传递到另一个方法,其中没有一个使用任何堆栈。 (然后通过将每个方法分解为可能的多个委托来具体化激活,每个委托都与一个激活对象关联。)
在连续传递风格中,根本没有堆栈,也根本无法判断你来自哪里;延续对象没有该信息。它只知道你下一步要去哪里。
这似乎是一个冠冕堂皇的理论胡言乱语,但是我们本质上是将 C# 和 VB 变成连续传递风格的语言在下一个版本中;即将到来的“异步”功能只是简单伪装的延续传递风格。在下一个版本中,如果您使用异步功能,您实际上将放弃基于堆栈的编程;无法查看调用堆栈并知道如何到达这里,因为堆栈经常是空的。
对于很多人来说,将延续具体化为调用堆栈以外的东西是一个很难理解的想法;这当然是为了我。但一旦你明白了,你就会明白它的意思。作为一个温和的介绍,这里有我写的一些关于这个主题的文章:
CPS 简介,并附有 JScript 示例:
http://blogs.msdn.com/b/ericlippert/archive/2005/08/08/recursion-part-four-continuation-passing-style.aspx http://blogs.msdn.com/b/ericlippert/archive/2005/08/08/recursion-part-four-continuation-passing-style.aspx
http://blogs.msdn.com/b/ericlippert/archive/2005/08/11/recursion-part- Five-more-on-cps.aspx http://blogs.msdn.com/b/ericlippert/archive/2005/08/11/recursion-part-five-more-on-cps.aspx
http://blogs.msdn.com/b/ericlippert/archive/2005/08/15/recursion-part-six-making-cps-work.aspx http://blogs.msdn.com/b/ericlippert/archive/2005/08/15/recursion-part-six-making-cps-work.aspx
这里有十几篇文章,首先深入研究 CPS,然后解释这一切如何与即将到来的“异步”功能一起工作。从底部开始:
http://blogs.msdn.com/b/ericlippert/archive/tags/async/ http://blogs.msdn.com/b/ericlippert/archive/tags/async/
支持延续传递风格的语言通常有一个神奇的控制流原语,称为“使用当前延续进行调用”,简称为“call/cc”。在这个 stackoverflow 问题中,我解释了“await”和“call/cc”之间的细微区别:
c# 5.0 中的新异步功能如何通过 call/cc 实现? https://stackoverflow.com/questions/4070237/how-could-the-new-async-feature-in-c-5-0-be-implemented-with-call-cc
要获取官方“文档”(一堆白皮书)、C# 和 VB 新“异步等待”功能的预览版以及支持问答论坛,请访问:
http://msdn.com/vstudio/async http://msdn.com/vstudio/async