← Back to context

Comment by Panzerschrek

5 hours ago

> A trait must follow so-called object safety rules to be used as a trait object

This seems for me to be a major design flaw of Rust. It tries to repurpose traits for dynamic polymorphism, even if this doesn't fit perfectly. C++ is more honest, it has two separate mechanisms for static polymorphism (templates) and dynamic polymorphism (inheritance).

In the contrary it’s one of the best design decisions of the language. The rules for object safety are the same C++ applies to virtual functions. On the other hand you don’t have to choose a priori whether you’ll need dynamic or static polymorphism, you can choose at use site, and the size of the objects do not pay for dynamic dispatch because the vtable pointer is kept together with the object pointer, not within the object.

  • > you can choose at use site

    This is possible in C++ too, but it may require extra work. But is it really needed that often to use both kinds of polymorphism for the same type?

    > the size of the objects do not pay for dynamic dispatch because the vtable pointer is kept together with the object pointer, not within the object.

    You have identical memory overhead in Rust and C++ if you store a single pointer to a polymorphic object. But if more than one such pointer is stored (if it's shared), Rust uses more memory, since it stores N virtual table pointers (together with each object pointer), where C++ stores exactly one virtual table pointer within the object itself.

    • The C++ design is optimised for the case where you're mostly storing Things everywhere and then at runtime code works out whether each particular Thing is a Customer, or a Product, or a Target, or an Artist, or what...

      I don't think even an LLM writes software like this, maybe somebody's Java 101 class teaches this, but frankly I think that's a bad way to teach even Java.

      The Rust approach optimises for cases where Customers and Products and Targets and Artists are stored and treated separately and if we do need the generic Thing somewhere it's pretty rare so we store the extra information only where needed.