There are some non-lint type things that would help in a safe mode. These all need type information; they're not just syntax.
- Can't keep a raw pointer. If you create one, it has to have local scope and cannot be copied to an outer scope. This is like a borrow in Rust, and limits the lifetime of the pointer. Most uses of raw pointers involve calling legacy code, and don't need much lifetime. Most trouble with pointers involves them outliving the thing to which they point.
- Can't read into or memcopy into any type that is not fully mapped. That is, all bit values have to be valid. Char OK, int OK, enum not OK, pointer not OK. This is better than prohibiting binary reads or memcopy, because programmers will not be tempted to bypass it.
- Casts into non fully mapped types are prohibited. If you need to convert something to a non fully mapped type, it requires a constructor, with checking.
That gives a sense of the general idea. Do enough analysis to see if something iffy is safe, and prohibit the cases which are not easy to show safe.
It's something I don't see Rust proponents address. It's easy to build a straw man argument of Rust vs. old-school C, but it's a more natural path to go from C to modern C++ than to go from C to Rust. You get to keep your compiler, build system, tools, libraries and indeed existing code.
See this for an example: https://news.ycombinator.com/item?id=21681395
https://people.gnome.org/~federico/blog/exposing-c-and-rust-...
And yet we see the same memory-safety bugs come up time and time again in supposedly-modern C++ programs. So either this modern way is not enough to avoid these classes of bugs, or people very quickly fall to the temptation to use unsafe constructs due to performance or just because it's easier to write.
We're humans. If there's an easier way to do something, even if it's less safe, we'll invariably do it sometimes. I like that Rust makes it harder to do so, and makes you explicitly say that you want to do something unsafe, which I imagine deters a lot of people from going down those paths. And when someone writes a memory-safety bug in unsafe Rust, they get much more egg on their face than if they were to write the same bug in C++.
The memory management issues in my C++ programs (recently, real-time audio stuff) are where I explicitly decide not to use modern C++ / automated memory management, and write my own allocators that rely on malloc/free or some variant (aligned_alloc, etc.)
In Rust I suppose I would just use an unsafe block and have the exact same issues.
Note that good unit testing, assertions and sanitizers generally take care of the issue.
Unit tests, assertions, and sanitizers are nice, but they demonstrably don't work; Chrome and Firefox use all three. They have hundreds of thousands or millions of tests, assertions on every other line, and all kinds of compile-time sanitizers but they still have hundreds of memory safety problems a year.
We built a new project in all "modern C++". It is 100% shared_ptr, unique_ptr, std::string, RAII, etc. It initially targeted C++17 specifically to get all the "modern C++" goodness.
It segfaults. It segfaults all the time. It is entirely routine for us to run a new build through the CI process and find segfaults. We fuzz it and find dozens of segfaults. Segfaults because of uninitialized memory. Segfaults because dereferencing pointers. Segfaults because running off the end of arrays. Segfaults because trusting input from the outside world ("the length of this payload is X bytes").
This is where the "modern C++" people tell me we must be doing it wrong. But the reality is that "modern C++" isn't as safe or as foolproof as the advocates say it is. But don't take my word for it - this whole thread is about Google people coming to the same conclusion.
Meanwhile I can throw a new dev at Rust and watch them go from zero to works in a week or so, and their code doesn't segfault, doesn't panic, and actually does what it is supposed to do the first time. Code reviews are easy because I don't have to ponder the memory safety and correctness of every line of code. Reasoning about unwrap() is trivial. Finding unsafe {} is trivial (and removing it is also usually easy).
And then one day I found Rust, and all those problems went away. I can now write fearless code, and I don't have to endure the stench of rotting bodies anymore.
True story.
Any progress on a C++ to Rust converter? Not a "transpiler". Something with enough smarts to figure out when to use native Rust arrays, not "offsets" to imitate pointer arithmetic. I'm surprised that one of the big C++ users, like Google, doesn't have a group doing that.
The guy who maintains it said in the reddit thread[2] about this same topic that the Google people have been sending him good PRs, which is presumably related to integrating Rust into Chrome.
[1] https://crates.io/crates/cxx [2] https://reddit.com/r/rust/comments/gpdorw/the_chromium_proje...