Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Neither of those is correct, as a legitimate reason. Rust does everything C++ does, as far as things happening invisibly. Everything Linus famously ranted about is there.

And, Rust has even more incompatibilities with fast-and-loose C memory use. There are reasons why C and C++ compilers have "sanitizer" modes. Those identify places where code would be surprisingly elided. Yes, C has those too.



Rust famously does not do implicit allocation or implicit nontrivial construction. It also famously doesn’t do implicit construction when concrete parameter types don’t match the types in function signatures, which is a common source of side effects (and memory corruption) in C++.

In general, Rust is more implicit than C, but significantly less implicit than C++. Moreover, the ways in which Rust is implicit are more consistent and less likely to introduce bugs.


You will need to cite evidence that implicit argument type conversion is a common source of memory corruption.


I figured it rose to the level of conventional wisdom. I don’t have a source to cite, because I’ve only dealt with it in random codebases.

As an anecdote: I had a codebase where a nontrivial constructor contained a “registry” of created objects, for introspection. The design contract for that part of the API included the assumption that all constructions would be explicit, but it wasn’t actually enforced. Later, someone did some subclassing and added some APIs that inadvertently performed a converting construction, resulting in broken invariants around offsets and members in the registry.

Was it a good design? No, it was terrible. But nothing stopped someone from writing it, and the codebase otherwise “did everything right” (C++11, warning flags out the wazoo, fuzzing, unit tests, etc.)

It was a real pain in the ass to debug, and it fundamentally couldn’t have happened in a Rust codebase. And that’s just one tiny corner.


How would you have achieved what that code was doing, in Rust?

Code written to assume it will only ever run in context X being made to run in context Y instead is a problem that happens in every language equally. It is prevented by making a predicate Z to report whether X, and asserting Z where it matters. It is not a product of conversion.

In Rust, you would have had a factory function for type A, and somebody would have made a factory function for B that called the one for A, provoking the same failure.

We still need evidence of the original claim that implicit argument type conversion is a common source of memory corruption. We already know that bad design breeds bugs.


Yes, you couldn’t do exactly that in Rust, and that’s a good thing. It was a bad design decision.

In Rust, the closest thing would probably be a shared Rc member for the registry and a non-owning indexing scheme (either weak references or something symbolic). But I’ve never actually seen a Rust codebase that needed to apply the registry pattern; it’s usually the wrong abstraction, like I said.

Edit: And no, replicating this pattern in Rust would not have produced the same failure. The failure mode in C++ resulted in exploitable memory corruption.


>Rust does everything C++ does, as far as things happening invisibly

These 4 things do not happen invisibly in rust:

code running on struct creation (it will be an explicit ::new() call)

code running on struct copying (it will be an explicit ::clone() call)

code running on struct moving (moving is always a memcpy in rust, no custom code can run).

Error handling flow control (no exceptions, error handling will at minimum be marked with a '?'). (yes panic exists but this is basically for the same purposes as a kernel panic).

Rust favours making things explicit, much more so than C++.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: