151

我已经看到它在编程中使用(特别是在 C++ 域中)并且不知道它是什么。大概这是一种设计模式,但我可能是错的。谁能举一个thunk的好例子?

4

12 回答 12

152

Athunk通常是指一小段代码作为函数调用,做一些小事情,然后JUMPs 到另一个位置(通常是函数)而不是返回给它的调用者。假设 JUMP 目标是一个普通函数,当它返回时,它将返回到 thunk 的调用者。

Thunks 可以用来高效地实现很多有用的东西

  • 协议转换——当从使用一种调用约定的代码调用到使用不同调用约定的代码时,可以使用 athunk来适当地转换参数。这仅在返回约定兼容的情况下才有效,但通常是这种情况

  • 虚函数处理——在 C++ 中调用多重继承基类的虚函数时,需要修复this指针以使其指向正确的位置。Athunk可以做到这一点。

  • 动态闭包——当你构建一个动态闭包时,闭包函数需要能够获得它被创建的上下文。可以构建一个小thunk的(通常在堆栈上),它在一些寄存器中设置上下文信息,然后跳转到实现闭包功能的静态代码。这里的 thunk 有效地为调用站点未提供的函数提供一个或多个隐藏的额外参数。

于 2010-04-15T00:32:59.210 回答
82

thunk 这个词在计算机科学中至少具有三个相关的含义。“重击”可能是:

  • 一段执行延迟计算的代码(类似于闭包)
  • 一些虚函数表实现的特性(类似于包装函数)
  • 机器数据从一种系统特定形式到另一种形式的映射,通常是出于兼容性原因

我通常看到它在第三种情况下使用。

http://en.wikipedia.org/wiki/Thunk

于 2010-04-14T22:25:58.850 回答
28

thunk 一词最初是指皇家雷达机构在其Algol60编译器中实现名称传递所使用的机制。通常,它指的是在引用明显静态的对象时引发动态行为的任何方式。这个术语是由 Brian Wichmann 发明的,当被要求解释 pass-by-name 时,他说:“好吧,你出去从内存中加载值,然后突然 - thunk - 你正在评估一个表达式。”

Thunks 已安装在硬件中(参见 KDF9,Burroughs 大型机)。有几种方法可以在软件中实现它们,所有这些都是机器、语言和编译器特定的。

该术语已被概括为超越名称传递,包括任何明显或名义上的静态数据引用引发动态行为的情况。相关术语包括“蹦床”和“未来”。

于 2015-07-18T03:25:19.450 回答
17

一些面向对象语言(如 C++)的编译器生成称为“thunk”的函数,作为在存在多重继承或虚拟继承时对虚拟函数调用的优化。

取自:http ://en.wikipedia.org/wiki/Thunk#Thunks_in_object-oriented_programming

于 2010-04-14T22:26:51.770 回答
8

这个问题已经在 SO 上提出过,请参阅:

什么是“thunk”,在 Scheme 或一般情况下使用?

据我所知,它类似于 lambda 语句,在需要对其进行评估之前,您可能不想返回该值;或者也可以将其与属性 getter 进行比较,该属性 getter 通过设计执行一些代码以返回值,同时具有更像变量的接口形式,但也具有可以通过继承或交换的多态行为通过换出函数指针,该指针将根据编译时或环境特征在运行时评估并返回一个值。

于 2010-04-14T22:27:47.950 回答
7

使用上有很大的差异。几乎普遍地,thunk 是一个(至少在概念上)异常小和简单的函数。它通常是某种适配器,可为您提供与某事或其他事物(某些数据、另一个功能等)的正确接口,但至少被视为几乎没有做其他事情。

它几乎就像语法糖的一种形式,除了(至少通常使用的)语法糖应该让事物看起来像人类读者想要看到的那样,而 thunk 是让事物看起来像编译器想要的那样看见。

于 2010-04-14T22:56:51.883 回答
5

我很苦恼地发现这个术语的一般“计算机科学”定义与我在历史上所知道的实际用法相匹配。我记得第一次现实生活中的遭遇是在 OS/2 天和 16-32 位转换中实际调用的地方。在今天的应用中,“thunking”似乎具有讽刺意味。

我粗略的一般理解是,thunk 是一个存根例程,它什么都不做,或者在系统之间的某种基本边界上路由,就像在提到的历史案例中一样。

因此,这种感觉就像从一个环境下降到另一个环境的联觉(隐喻/作为明喻)发出“砰砰”的声音。

于 2012-01-26T13:52:39.397 回答
5

我要查一下,但我认为thunking是 32 位处理器用来运行传统 16 位代码的过程。

我曾经用它来比喻你必须如何限制你说话的速度以及在与愚蠢的人交谈时使用什么词。

是的,它在 Wikipedia 链接中(关于 32 位的部分,不是我的书呆子)。

https://en.wikipedia.org/wiki/Thunk

许多关于互操作性 thunk 的文献都涉及各种 Wintel 平台,包括 MS-DOS、OS/2、[8]Windows[9][10] 和 .NET,以及从 16 位到 32 位内存寻址的转换. 随着客户从一个平台迁移到另一个平台,thunk 对于支持为旧平台编写的遗留软件至关重要。

(重点由我添加)

于 2010-04-14T22:33:39.077 回答
1

我所知道的“thunk”最早的用法是从 50 年代后期开始,它指的是函数调用中的 Algol60 pass-by-name 参数评估。Algol 最初是一种规范语言,而不是一种编程语言,并且存在一些关于如何在计算机上实现 pass-by-name 的问题。

解决方案是通过本质上是 lambda 的入口点。当被调用者评估参数时,控制失败 - thunk!- 进入调用者的上下文,其中 lambda 被评估并且它的结果成为被调用者中参数的值。

在标记的硬件中,例如 Burroughs 机器,评估是隐式的:参数可以像普通的按值传递一样作为数据值传递,或者通过名称传递的 thunk 传递,在参数元数据中具有不同的标签. 加载操作硬件检查标记并返回简单值或自动调用 lambda thunk。

于 2020-05-18T09:07:58.843 回答
0

根据Kyle Simpson 的定义,thunk是一种从异步代码中抽象出时间组件的方法。

于 2018-01-21T02:37:20.937 回答
0

早期版本的《新黑客词典》声称thunk是一个不带参数的函数,它是一个简单的深夜解决方案,可以解决一个特别棘手的问题,其中“thunk”是“think”的假定过去时,因为他们应该早就想到了。

于 2021-02-26T17:48:58.757 回答
0

在 OCaml 中,它是一个将单元“()”作为参数的函数(不带参数,通常用于副作用)

于 2021-03-28T21:40:11.820 回答