Rust ↔ C++
| Аспект | Rust | C++ |
|---|---|---|
| Тривиальная перемещаемость (trivial relocatability) | Все перемещения — это memcpy | Самоссылающиеся типы; конструкторы перемещения могут иметь побочные эффекты |
| Безопасность уничтожения | Drop::drop() только в исходном месте | Деструктор может выполняться для объектов, из которых уже выполнено перемещение |
| Безопасность исключений | Паники (abort или unwind) | Исключения (unwind) |
| Стабильность ABI | Явно нестабилен | Зависит от поставщика |
Даже если бы удалось обойтись взаимодействием через C, некоторые области языков всё равно влияют на FFI:
Тривиальная перемещаемость
На стороне Rust нельзя безопасно перемещать объекты C++; их нужно закреплять (pin) или хранить в куче C++.
В Rust перемещение объектов, которое происходит при присваивании или передаче по значению, всегда копирует значения побитово.
C++ позволяет пользователям задавать собственную семантику: они могут перегружать оператор присваивания и создавать конструкторы перемещения и копирования.
Это влияет на взаимодействие, потому что самоссылающиеся типы становятся естественными в высокопроизводительном C++. Собственные конструкторы могут поддерживать инварианты безопасности, даже когда объект меняет своё положение в памяти.
Объекты с той же семантикой невозможно определить в Rust.
Безопасность уничтожения
Семантика объектов C++, из которых выполнено перемещение, не соответствует Rust; нужно не допустить, чтобы Rust «перемещал» типы C++.
Безопасность исключений
Ни одно из них не может безопасно пересекать границу другого; оба должны перехватывать исключения на границе.