Rust против C++: как dyn Trait устроен в памяти

Visualizing Rust's Vtables: How dyn Trait Works In Memory

Rust против C++: как dyn Trait устроен в памяти

Автор, изучая Rust, сравнивает его подход к полиморфизму с C++. В статье визуализируется, как работают vtable и dyn Trait в памяти, объясняется разница между статической и динамической диспетчеризацией, а также рассматриваются zero-sized types. Приводятся примеры кода и результаты экспериментов, показывающие, что в Rust выбор диспетчеризации происходит на месте вызова, а не на уровне класса, как в C++.

Rust делает то же самое с вашей ментальной моделью: когда вы вверх ногами в воздухе, вам приходится сознательно перестраивать всё ощущение того, как работает ваше тело.
  1. tialaramex

    В статье есть раздел про Object Safety, я проверил — статья написана на этой неделе, но «Object Safety» — сбивающее с толку название для этой идеи, и поэтому уже некоторое время Rust называет эту идею «dyn compatibility», потому что самое главное, что вы получаете, если трейт «dyn-совместим», — это возможность использовать «dyn Trait» — https://doc.rust-lang.org/1.98.1/reference/items/traits.html...

    По этой ссылке правила объяснены и более полно.

    [Правка: понял, что в конце статьи это объясняется — автор начал писать её месяцы назад, вероятно, до того, как узнал об улучшенном названии «dyn compatibility»]

  2. Panzerschrek

    > Трейт должен соответствовать так называемым правилам object safety, чтобы использоваться как объект трейта.

    Мне это кажется серьёзным недостатком дизайна Rust. Он пытается приспособить трейты для динамического полиморфизма, даже если это не совсем подходит. C++ более честен: у него есть два отдельных механизма — для статического полиморфизма (шаблоны) и для динамического (наследование).

  3. Panzerschrek

    Однажды я столкнулся с хитрой ошибкой, связанной с жирными указателями (содержащими таблицы виртуальных функций) в Rust. Два таких указателя могут различаться, даже если они ссылаются на один и тот же объект, потому что (по какой-то причине) компилятор может создать две (или даже больше) копии таблицы виртуальных функций и использовать их в разных местах.

  4. evmar

    В моём собственном путешествии открытий мне очень помог сайт https://cheats.rs/, особенно его раздел «memory layout» с визуализациями. (Я не связан с этим сайтом, просто довольный читатель!)

  5. returningfory2

    Очень хорошо. В качестве продолжения было бы интересно также восстановить структуру самой vtable. Полагаю, это список указателей на реализации методов?

Ещё за этот день

2026-09-05