Rust ↔ C++
| 観点 | Rust | C++ |
|---|---|---|
| トリビアル再配置可能性 | すべてのムーブは memcpy | 自己参照型やムーブコンストラクタには副作用があり得る |
| 破棄の安全性 | 元の場所でのみ Drop::drop() が呼ばれる | ムーブ後のオブジェクトに対してデストラクタが実行される場合がある |
| 例外安全性 | panic(abort または unwind) | 例外(unwind) |
| ABI の安定性 | 明示的に不安定 | ベンダー依存 |
C を介した相互運用を避けることができたとしても、FFI に影響する言語上の領域がいくつかあります:
トリビアル再配置可能性
Rust 側で C++ オブジェクトを安全にムーブすることはできません。pin するか、C++ ヒープ上に保持する必要があります。
Rust では、代入時や値渡し時に発生するオブジェクトのムーブは、常に値をビット単位でコピーします。
C++ では、代入演算子のオーバーロードやムーブコンストラクタ、コピーコンストラクタの作成を許可することで、ユーザーが独自のセマンティクスを定義できます。
これは相互運用に影響します。高性能な C++ では自己参照型が自然に現れるためです。カスタムコンストラクタは、オブジェクトがメモリ内で位置を移動しても、安全性の不変条件を維持できます。
同じセマンティクスを持つオブジェクトを Rust で定義することは不可能です。
破棄の安全性
ムーブ後の C++ オブジェクトのセマンティクスは対応付けられないため、Rust が C++ 型を「ムーブ」しないように防ぐ必要があります。
例外安全性
どちらも安全に相手側へまたがって渡ることはできないため、両方とも境界で捕捉する必要があります。