3 ms·
> No, the problem here is very real - rust doesn't have a reasonable c++ interop story, which means you have to rewrite potentially very large amounts of code
by pcwalton 5y ago
> No, the problem here is very real - rust doesn't have a reasonable c++ interop story, which means you have to rewrite potentially very large amounts of code at once and hope you don't regress anything. At the same time you have to continue normal development work, which is necessarily still C++, because again, you can't adopt rust in small sections.
This was a somewhat more accurate summary a few years ago (though saying "you can't adopt rust in small sections" ignores the fact that Firefox among others did just that), but the cxx crate has made huge strides lately, and it's much more feasible now to interoperate at a deep level between Rust and C++. (In fact, dealing with this interoperability constitutes a large part of my job nowadays, and thanks to cxx it performs swimmingly.) We're even starting to talk about advanced features like seamless C++ async/await support in cxx.
- haberman 5y agoCan Rust instantiate a C++ template? How do you interop across interfaces that use templates?
- pcwalton 5y agoYes! The tutorial for cxx shows how you can use common templated types like std::vector: https://cxx.rs/index.html https://cxx.rs/index.html More details are in the crate documentation: https://docs.rs/cxx/1.0.49/cxx/ https://docs.rs/cxx/1.0.49/cxx/ Note that the philosophy of cxx isn't to support all of C++'s semantics (templates make this impossible in the limit as Rust has no SFINAE rule for example), but rather to support the important use cases that arise in practice. It's also worth noting that, these days, bindgen has support for instantiating C++ templates, though it operates at a much lower level. Compared to cxx, bindgen is oriented more toward being comprehensive than being easy.
- vlovich123 5y agoHave you gotten a chance to use cxx in a large “production” “legacy” c++ codebase? It’s great but there’s quite a few roadblocks that I encountered even trying something I would have considered that should be “easy”. I could easily imagine that Chromium would have an even tougher time. Some highlights: * if you’re not careful, you’ll end up with linkage issues if you link in multiple crates. This means 1 uber create that has all your Rust dependencies. This can mess with parallelism in your build since Cargo isn’t coordinating with the broader system. * speaking of build systems, chromium probably wouldn’t use create meaning extra build system integration, especially since they don’t use Bazel/Blaze. * cxx still can’t pass across certain types (Arc and Option being the big ones) and is missing a general story for extending it with custom types. * cxx can frequently cause you to have to reach to unsafe anyway because the lifetime semantics you want to express cannot be done in pure Rust because the other half lives in c++. Don’t get me wrong. Rust is fantastic and a joy to use. Dismissing the challenges a project like Chromium has as “they just want to stick to c++” isn’t a fair look at the situation. Lots of smart people work on these projects and are keenly aware of Rust. Additionally managers and executives are keenly aware of the security benefits so there’s definitely downward pressure to try to adopt these (and large efforts spent investigating how to enable this whole maintaining developer velocity).
- haberman 5y agoThanks for the references, I'll definitely have to check those out.
- verdagon 5y agoI would love your opinion on whether migrating to Rust is a good idea for us, since you're experienced in this realm. My team has a Java project that's written in a modern OO style. We defined "modern" OO as encapsulation and polymorphism, without inheritance, and it fits our use case very well. We don't want to give up the benefits we get from the OO architecture, for good reasons that I won't get into here (because I don't want this to de-rail into a OO bash-fest, as fun as they are!) The conundrum: In my experience, Rust doesn't support polymorphism very well. When the borrow checker meets polymorphism, a lot of state is forced into parameters (state which is inherent; we already keep state to an absolute minimum), which opens it up to mutation from all sorts of places; not very encapsulated. We can have a bunch of private member Rc<RefCell<T>>s instead of bringing in all state via parameters, but it's unidiomatic, and in the end we'd probably have something slower and less safe than our original Java program. The question: Is there any way to make Rust a good fit for a use case like ours? (The same problems would apply to C++ codebases, though it's a little more convincing for them, since C++ isn't as safe as Java)
- brundolf 5y agoNot the GP, but is your problem that you have a complex object-graph without clearly defined owners of objects (as is common in GC'd languages, especially OOP ones)?
- verdagon 5y agoThere's a pretty clear tree of ownership, actually. Looking at any given component, it's fairly easy to know when a component is a "subcomponent" (owned) or whether it's a reference to some other component elsewhere (borrowed). Some of us are C++ veterans, so we tend to think in terms of single ownership no matter what language we're in. There are a few references in our "main" (so to speak) where its ownership would be clearer if we stored them in local variables and then handed them to the only component that used it, but that's a cosmetic concern, really. There are very few (if any) places where we actually make use of Java's shared ownership. The only place I can think of is where we cache some files, and farm out "shared" references to any file. Still, at that point, the cache could be considered the owner, with a slight adjustment.
- glandium 5y agocxx doesn't necessarily help for cases like refactoring legacy C++ code. It seems to require more work than bindgen. I suspect switching to cxx in Firefox, to replace bindgen, would be quite involved.