it-swarm-ja.com

一般的なC ++ラッパーでRustの所有権モデルを実現することは可能ですか?

Rustの同時実行の安全性に関するこの記事を見てください。

http://blog.Rust-lang.org/2015/04/10/Fearless-Concurrency.html

これらのアイデアのいくつがC++ 11(またはそれ以降)で実現できるのかと思っていました。特に、渡される可能性のある任意のメソッドに所有権を転送する所有者クラスを作成できますか? C++には変数を渡す方法が多すぎて不可能だと思われますが、クラスやテンプレートにいくつかの制限を加えて、すべてのメソッドパスでいくつかのテンプレートコードが実行されるようにすることはできますか?

16
Brannon

C++には、パラメーターを関数に渡す方法が3つあります。値、左辺値参照、右辺値参照です。これらのうち、値による受け渡しは、呼び出された関数が独自のコピーを受け取るという意味で所有権を作成します。rvalue参照による受け渡しは、値が消費される可能性があること、つまり、呼び出し元によって使用されなくなることを示します。左辺値参照で渡すと、オブジェクトは呼び出し元から一時的に借用されます。

ただし、これらは「慣例による」傾向があり、コンパイラーが常にチェックできるとは限りません。また、std::move()を使用すると、誤って左辺値参照を右辺値参照に変換できます。具体的には、3つの問題があります。

  • 参照は、参照するオブジェクトよりも長く存続できます。 Rustのライフタイムシステムはこれを防ぎます。

  • いつでも複数の変更可能/非const参照がアクティブになる可能性があります。 Rustの借用チェッカーはこれを防ぎます。

  • 参照をオプトアウトすることはできません。呼び出された関数のシグネチャを知らなければ、その関数がオブジェクトへの参照を作成するかどうかを呼び出しサイトで確認することはできません。したがって、クラスの特別なメソッドを削除したり、「参照なし」スタイルガイドに準拠して呼び出しサイトを監査したりすることによって、参照を確実に防止することはできません。

寿命の問題は、基本的なメモリの安全性に関するものです。もちろん、参照されるオブジェクトの有効期限が切れたときに参照を使用することは違法です。しかし、オブジェクト内に参照を保存するとき、特にそのオブジェクトが現在のスコープよりも長く存続するときは、存続期間を忘れがちです。 C++型システムはオブジェクトの有効期間をまったくモデル化しないため、これを考慮することができません。

std::weak_ptrスマートポインターは、プレーンリファレンスと同様に所有権のセマンティクスをエンコードしますが、参照されるオブジェクトはshared_ptrを介して管理される必要があります。つまり、参照カウントされます。これはゼロコストの抽象化ではありません。

C++にはconstシステムがありますが、これはオブジェクトを変更できるかどうかは追跡しませんが、オブジェクトを変更できるかどうかを追跡しますその特定の参照を通じて。これは、「大胆不敵な同時実行」を十分に保証するものではありません。対照的に、Rustは、唯一の参照であるアクティブな変更可能な参照がある場合(「私がこのオブジェクトを変更できるのは私だけです」)、そして変更不可能な参照がある場合オブジェクトへのすべての参照は変更できません(「オブジェクトから読み取ることはできますが、誰も変更することはできません」)。

C++では、ミューテックスを備えたスマートポインターを介してオブジェクトへのアクセスを保護したくなるかもしれません。しかし、上で説明したように、参照を取得すると、期待される寿命から逃れることができます。したがって、そのようなスマートポインターは、管理対象オブジェクトへの単一のアクセスポイントであることを保証できません。ほとんどのプログラマーは自分自身を妨害したくないので、そのようなスキームは実際に機能するかもしれませんが、型システムの観点からは、これはまだ完全に不健全です。

スマートポインターの一般的な問題は、それらがコア言語の上にあるライブラリであることです。コア言語機能のセットは、これらのスマートポインターを有効にします。 std::unique_ptrにはmove-constructorsが必要です。ただし、コア言語の欠陥を修正することはできません。関数を呼び出すときに暗黙的に参照を作成する機能と、ぶら下がる参照を一緒に持つ機能は、コアC++言語が適切でないことを意味します。可変参照を単一の参照に制限できないということは、C++が、いかなる種類の同時性を伴う競合状態に対する安全性を保証できないことを意味します。

もちろん、多くの点でC++とRustは、特に静的に決定されたオブジェクトのライフタイムの概念に関して、嫌いではなく似ています。しかし、それは可能正しいC++プログラム(プログラマーが間違いを犯さない限り)、Rust guarantees説明されているプロパティに関する正確さ)。

8
amon