「サンク」とは何ですか?


130

私はそれがプログラミング(特にC ++ドメイン)で使用されているのを見てきましたが、それが何であるかはわかりません。多分それはデザインパターンですが、私は間違っているかもしれません。誰もがサンクの良い例を挙げられますか?


10
参考までに、サンクは「トランポリン」と呼ばれることもあります(一般的なケースでは、C ++ドメインにはない場合があります)。
Michael Burr

@MichaelBurr、私が使用した「トランポリン」という用語が使用されている唯一のコンテキストは迂回路であり、そのコンテキストではトランポリンはサンクではありません。
user34660

1
用語は特定の定義がないもののタイプであり、定義が異なります。
user34660

回答:


132

Aはthunk通常、関数と呼ばれるコードの小片を意味するいくつかの小さなものを行い、その後、JUMP代わりに、呼び出し元に戻るの別の場所(通常は関数)に対するS。JUMPターゲットが通常の関数であると仮定すると、戻ると、サンクの呼び出し元に戻ります。

サンクは、多くの便利なものを効率的に実装するために使用できます

  • プロトコル変換-ある呼び出し規約を使用するコードから別の呼び出し規約を使用するコードに呼び出す場合、a thunkを使用して引数を適切に変換できます。これは、戻り規則に互換性がある場合にのみ機能しますが、多くの場合そうです

  • 仮想関数の処理-C ++で多重継承された基本クラスの仮想関数を呼び出す場合this、正しい場所を指すようにするには、ポインターを修正する必要があります。A thunkはこれを行うことができます。

  • 動的クロージャ-動的クロージャを構築するとき、クロージャ関数はそれが作成されたコンテキストに到達できる必要があります。thunkいくつかのレジスタでコンテキスト情報を設定し、クロージャの関数を実装する静的なコードにジャンプする小さな(通常はスタック上に)ビルドできます。ここでのサンクは、呼び出しサイトによって提供されない、関数への1つ以上の隠された追加の引数を効果的に提供しています。


13
これは、さまざまなことを実装するために通常のユースケースでサンク通常行うことでなく、サンク何であるかを説明するため、最良の説明です。他の回答は、一般的な考えではなく、それらの特定の実装に焦点を合わせすぎています。
SasQ 2014年

他のコンパイラについてはわかりませんが、特にVisual Studio はサンクが非常に好きなようです。私の知る限り、使用するのは次のとおりです:アジャスターサンク(調整用this)、デフォルト/コピーコンストラクタークロージャー(ユーザー提供のデフォルトパラメーターとのCRT統合、主にDLLエクスポートまたは配列の構築用)、vcallサンク(ポインターを確実に-member-functionsは仮想関数で適切に機能します)、vtordispサンク(仮想ベースから仮想関数を継承およびオーバーライドし、ユーザー提供のctorおよび/またはdtorも持つクラスの場合)、ネイティブラッパー(マネージC ++ / CLIを呼び出すため
Justin Time) -モニカ

ネイティブISO C ++コードからの関数)、および「UDT returning」と呼ばれるもの(演算子によって返されるユーザー定義型を調整するためのサンクのように見えますが、それを生成する方法がわかりません。非推奨だと思います)。おそらく他にもあります。マイクロソフトを言うことは決してできないと思いますthunk。デカルトは誇りに思うでしょう。
ジャスティンタイム-モニカを2016年

80

サンクという言葉には、コンピューターサイエンスで少なくとも3つの関連する意味があります。「サンク」は次のようなものです。

  • 遅延計算を実行するコード(クロージャーと同様)
  • 一部の仮想関数テーブル実装の機能(ラッパー関数に類似)
  • 通常は互換性の理由から、あるシステム固有の形式から別の形式へのマシンデータのマッピング

私は通常、それが3番目のコンテキストで使用されるのを見てきました。

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


3
面白い; 私は通常、2番目の形式を聞きますが、それはあなたがより頻繁にどのような種類の仕事をするかによると思います
Michael Mrozek

具体的には、マシンコードの非常に短いブロックが自動的に生成されることによって関連します。最初のケースでさえ、通常はプリコンパイルされた実装関数にコンテキストを与えるだけです。
Simon Buchan 2010

21

サンクという用語は、元々は、Algol60コンパイラでの名前渡しのRoyal Radar Establishment実装で使用されるメカニズムを指していました。一般に、明らかに静的なオブジェクトを参照するときに動的な動作を誘発する方法を指します。この用語は、名前渡しを説明するように求められたとき、「メモリから値をロードするために出かけていき、そこで突然、サンク-式を評価している」と述べたBrian Wichmannによって考案されました。

サンクはハードウェアに組み込まれています(KDF9、バロウズのメインフレームを参照)。それらをソフトウェアに実装する方法はいくつかありますが、それらはすべて、マシン、言語、コンパイラ固有のものです。

この用語は、名前による受け渡しを超えて一般化されており、明らかにまたは名目上静的なデータ参照が動的な振る舞いを引き起こすあらゆる状況を含みます。関連用語には、「トランポリン」と「未来」があります。


2
語源をありがとう。定義がテーブル内の任意のルックアップであると思われるプログラミング用語は嫌いです。
ロスロジャース


7

使用にはかなりのばらつきがあります。ほとんど普遍的に、サンクは(少なくとも概念的には)非常に小さくてシンプルな関数です。これは通常、何らかのデータ(別のデータ、別の関数など)への正しいインターフェイスを提供するアダプタの一種ですが、少なくとも他のことはほとんど行われていないと見なされています。

これは、(少なくとも通常使用されるように)構文糖が、人間の読者が見たいように見せるようになっていることを除いて、構文糖の一種に似ています。サンクは、コンパイラが望んでいるように外観を作ることです見てください。


2
私には構文糖の反対のように
聞こえ

2
コンパイラの構文糖は?完全ではないが、ほぼ完全に構文糖とは異なります。
ダンカン

2
たぶん、構文ソウナー?
ジャスティンタイム-モニカ

7

この質問はすでにSOで質問されています。以下を参照してください。

Schemeまたは一般的に使用される「サンク」とは何ですか?

私が言うことができることから、それはラムダステートメントに似ており、評価する必要があるまで値を返したくない場合があります。または、設計によって値を返すためにコードを実行するプロパティゲッターと比較することもできますが、変数のように出くわすインターフェイスのフォームを持っていますが、継承またはコンパイル時または環境の特性に基づいて、実行時に値を評価して返す関数ポインタを交換する。


5

この用語の一般的な「コンピュータサイエンス」の定義が、歴史的に知られている事実上の使用法と一致しないことに私は悩みました。OS / 2日と16-32ビットの移行で実際に呼ばれた場所を思い出すことができる最初の現実の出会い。「サンク」は、今日のアプリケーションでは皮肉のように見えます。

私の大まかな一般的な理解は、サンクは、何もしないか、前述の歴史的なケースのようにシステム間の種類のある基本的な境界を越えてルーティングするスタブルーチンであるということです。

つまり、感覚は、ある環境から別の環境に落とされて(比喩的に/類義語として)「サンク」サウンドを作ることの共感覚のようなものです。


1
興味深いヒント。この言葉の実際の語源についても疑問に思っていたところ、「ブッシュテレグラフ」を演奏している人を想像した。
SasQ 2014年

5

これを調べますが、サンクは32ビットプロセッサがレガシー16ビットコードを実行するために採用したプロセスだと思いました。

私はこれを、あなたが話す速さを制限しなければならない方法や、愚かな人々と話すときに使用する単語の類推として使用していました。

ええ、それはウィキペディアのリンクにあります(32ビットに関する部分で、私の神経学ではありません)。

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

相互運用性サンクに関する多くの文献は、MS-DOS、OS / 2、[8] Windows [9] [10] 、. NETを含むさまざまなWintelプラットフォーム、および16ビットから32ビットへのメモリアドレス指定に関するものです。。顧客が1つのプラットフォームから別のプラットフォームに移行するにつれて、古いプラットフォーム用に作成されたレガシーソフトウェアをサポートするためにサンクが不可欠になりました。

(私が追加した強調)


1

私が知っている「サンク」の最も初期の使用法は、関数呼び出しでのAlgol60の名前渡しの引数の評価に関して、50年代後半のものです。Algolはもともとプログラミング言語ではなく仕様言語であり、名前渡しをコンピューターに実装する方法についていくつかの質問がありました。

解決策は、本質的にラムダであったもののエントリポイントを渡すことでした。呼び出し先がパラメータを評価すると、コントロールが失敗しました-サンク!-ラムダが評価された呼び出し元のコンテキストに、その結​​果が呼び出し先のパラメーターの値になりました。

バローズマシンなどのタグ付きハードウェアでは、評価は暗黙的でした。引数は、通常の値渡しの場合と同様にデータ値として、または名前渡しの場合はサンクによって、引数メタデータに異なるタグを付けて渡すことができました。 。ロード操作ハードウェアがタグをチェックし、単純な値を返すか、ラムダサンクを自動的に呼び出しました。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.