151

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

4

12 に答える 12

152

Aは通常、関数として呼び出され、小さなことを実行してから、呼び出し元に戻るのではなく、別の場所(通常は関数)に移動thunkする小さなコードを指します。JUMPJUMPターゲットが通常の関数であると仮定すると、JUMPターゲットが戻ると、サンクの呼び出し元に戻ります。

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

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

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

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

于 2010-04-15T00:32:59.210 に答える
82

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

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

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

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

于 2010-04-14T22:25:58.850 に答える
28

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

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

この用語は、名前によるパスを超えて一般化され、明らかにまたは名目上静的なデータ参照が動的な動作を引き起こす状況を含みます。関連用語には、「トランポリン」と「将来」が含まれます。

于 2015-07-18T03:25:19.450 に答える
17

C ++などのオブジェクト指向言語用の一部のコンパイラは、複数または仮想継承が存在する場合の仮想関数呼び出しの最適化として、「サンク」と呼ばれる関数を生成します。

取得元:http ://en.wikipedia.org/wiki/Thunk#Thunks_in_object-Oriented_programming

于 2010-04-14T22:26:51.770 に答える
8

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

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

私の知る限り、これはラムダステートメントに似ています。ラムダステートメントでは、評価が必要になるまで値を返したくない場合があります。または、プロパティゲッターと比較することもできます。このプロパティゲッターは、値を返すためにコードを実行する一方で、変数のようなインターフェイスフォームを持ちながら、継承または継承によってスワップアウトできる多態的な動作を備えています。コンパイル時または環境特性に基づいて実行時に値を評価して返す関数ポインタを交換する。

于 2010-04-14T22:27:47.950 に答える
7

使用にはかなりのバリエーションがあります。ほとんどの場合、サンクは(少なくとも概念的には)非常に小さくて単純な関数です。これは通常、何か(一部のデータ、別の関数など)への正しいインターフェイスを提供するある種のアダプターですが、少なくとも他のことはほとんど行っていないように見えます。

これは、(少なくとも通常使用される)構文糖衣が人間の読者が見たいように見えるようにすることと、サンクがコンパイラーが望むように見えるようにすることを除いて、ほぼ構文糖衣の形式に似ています見てください。

于 2010-04-14T22:56:51.883 に答える
5

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

私はこれを、話す速度を制限する方法や、愚かな人と話すときに使用する言葉を制限する方法の例えとして使用していました。

ええ、それはウィキペディアのリンクにあります(私のオタクではなく、32ビットに関する部分です)。

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

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

(私が強調したもの)

于 2010-04-14T22:33:39.077 に答える
5

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

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

つまり、感覚は、ある環境から別の環境に落とされて(比喩的に/直喩として)「サンク」な音を出すという共感覚のようなものです。

于 2012-01-26T13:52:39.397 に答える
1

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

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

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

于 2020-05-18T09:07:58.843 に答える
0

カイルシンプソンの定義によると、サンクは非同期コードからタイムアウトコンポーネントを抽象化する方法です。

于 2018-01-21T02:37:20.937 に答える
0

The New Hacker's Dictionaryの以前のバージョンでは、サンクは引数をとらない関数であり、特にトリッキーな問題に対する単純な深夜の解決策であり、「サンク」は「考える」の過去形と見なされていると主張していました。彼らはずっと前にそれをサンクするべきでした。

于 2021-02-26T17:48:58.757 に答える
0

OCamlでは、単位「()」をパラメータとして取る関数です(パラメータをとらない、副作用によく使われます)

于 2021-03-28T21:40:11.820 に答える