什么是“沉重的”?


130

我已经看到它用于编程(特别是在C ++域中),却不知道它是什么。大概这是一种设计模式,但我可能是错的。任何人都可以举出一个很好的例子吗?


10
就像FYI一样,一个笨拙的人有时也被称为“蹦床”(一般情况下,在C ++域中可能不是)。
Michael Burr 2010年

@MichaelBurr,我看到的唯一使用“蹦床”一词的地方是Detours,在这种情况下,蹦床不是笨拙的东西。
user34660 '17

1
该术语是没有特定定义的事物的类型,因此其定义有所不同。
user34660 '17

Answers:


132

thunk通常,A 是指称为功能的一小段代码,先做一些小事情,然后JUMP转到另一个位置(通常是一个功能),而不是返回到其调用方。假设JUMP目标是一个正常函数,当它返回时,它将返回到thunk的调用者。

Thunk可以用来有效地实现许多有用的东西

  • 协议转换-从使用一种调用约定的代码调用到使用另一种调用约定的代码时,可以使用a thunk适当地翻译参数。这仅在返回约定兼容时才有效,但通常是这种情况

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

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


13
这是最好的解释,因为它解释的thunk什么什么,而不是它通常不会在典型使用案例来实现不同的事情。其他答案过于注重那些特定的实现方式,而不是总体思路。
SasQ 2014年

不确定其他编译器,但特别是Visual Studio似乎喜欢重击。据我所知,它使用:调整器thunk(以进行调整this),默认/复制构造函数闭包(以更好地CRT集成用户提供的默认参数,主要用于DLL导出或构造数组),vcallthunk(以确保指向-member-functions可以与虚拟函数一起正常使用),vtordispthunk(用于从虚拟基础继承并覆盖虚拟函数的类以及具有用户提供的ctor和/或dtor的类),本机包装器(以调用托管C ++ / CLI
Justin Time -恢复莫妮卡

函数来自本地ISO C ++代码)和一个称为“ UDT returning”的东西(它似乎在调整操作员返回的用户定义类型时很麻烦,但我不确定如何生成它;我认为已过时了)。可能还有其他人。我猜你永远不能拒绝微软thunk。笛卡尔会为之骄傲。
贾斯汀时间-恢复莫妮卡

80

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

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

我通常看到它在第三个上下文中使用。

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


3
有趣; 我通常会听到第二种形式,但是我想这取决于您更常从事哪种工作
Michael Mrozek 2010年

具体而言,通过自动生成非常短的机器代码块来进行关联-甚至第一种情况通常也只是为预编译的实现功能提供上下文。
西蒙·布坎

21

“ thunk”一词最初指的是Royal Radar Establishment在其Algol60编译器中通过传递名称使用的机制。通常,它指的是在引用看似静态的对象时诱发动态行为的任何方式。该术语是由Brian Wichmann发明的,他在被要求解释传递名字时说:“好吧,您出去从内存中加载值,然后突然-笨拙地-在这里评估表达式。”

已将thunk放入硬件中(参见KDF9,Burroughs大型机)。有几种方法可以用软件实现它们,所有方法都是机器,语言和特定于编译器的。

该术语已经超越了“通名”的范围,可以包括任何明显或名义上静态的数据引用引起动态行为的情况。相关术语包括“蹦床”和“未来”。


2
感谢您的词源。我讨厌编程术语,这些术语的定义似乎是在表中的任意查找。
罗斯·罗杰斯


7

使用上有很大的差异。几乎从总体上讲,thunk是一个(至少在概念上)异常小而简单的函数。它通常是某种适配器,可为您提供正确的接口,以连接某些事物或其他事物(某些数据,另一个功能等),但至少起着其他作用。

它几乎类似于一种语法糖,除了(至少通常使用)语法糖可以使事物看起来像人类读者希望看到的样子,而笨拙的东西可以使事物看上去就像编译器想要的样子看见。


2
听起来像语法糖的相反:)
Laserallan 2010年

2
那么编译器的语法糖呢?几乎但不是完全不像语法糖。
邓肯

2
也许是句法征兆者?
贾斯汀时间-恢复莫妮卡

7

已经在SO上询问了此问题,请参见:

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

据我所知,它类似于lambda语句,在这里您可能不希望返回值,直到需要评估它为止。或者也可以将其与属性获取器进行比较,该属性获取器在设计上执行一些代码以返回值,同时使接口形式更像是变量,但是具有可通过继承或继承交换掉的多态行为。通过换出将根据编译时或环境特性在运行时求值并返回值的函数指针。


5

令我感到困扰的是,没有找到与该术语的实际用法相匹配的通用“计算机科学”定义,正如我在历史上所知道的那样。我记得真实的第一次遭遇是在OS / 2天和16-32位转换中真正被称为的地方。如今,“ thunking”在其应用中似乎具有讽刺意味。

我粗略的理解是,thunk是一个存根例程,它根本不执行任何操作,也不像上述历史案例那样跨系统之间的某种基本边界进行路由。

因此,感觉就像是从一种环境掉落到另一种环境(隐喻地/作为一个比喻)发出一种“沉闷”的声音的联觉。


1
有趣的提示。我也想知道这个词的实际词源,并且我想像人们在玩“布什电报”,在那里,流中的一个人默默地(在许多情况下是不知不觉中)改变了消息的方式。
SasQ 2014年

5

我将对此进行查找,但是我认为thunk是32位处理器用来运行旧版16位代码的过程。

我曾经用它作为类比,您必须限制说话的速度以及与愚蠢的人说话时使用的单词。

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

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

有关互操作性问题的许多文献都涉及各种Wintel平台,包括MS-DOS,OS / 2,[8] Windows [9] [10]和.NET,以及从16位到32位内存寻址的过渡。。随着客户从一个平台迁移到另一个平台,对支持为旧平台编写的旧版软件的功能,重击已变得至关重要。

(我加强调)


1

我知道的最早的“ thunk”用法是从50年代后期开始引用函数调用中的Algol60传递名称实参评估。Algol最初是一种规范语言,而不是编程语言,并且有人对如何在计算机上实现“按名称传递”存在疑问。

解决方案是通过本质上是lambda的入口点。当被调用者评估参数时,控制权就落空了!-在评估lambda的调用方上下文中,结果成为被调用方中参数的值。

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.