I was at a lecture about security in C/++ code a couple of weeks ago. His conclusion was basically:
> There are no silver bullets with regards to safety in C/++ code; in order to achieve security, the programmer has to pay the price of being forever vigilant.
A lot of the complexity of Rust is for eliminating security pitfalls which are inherent in C/++.
It is common to use ARC and unsafe shared memory access in Rust. This defeats the purpose of this complexity. You can't isolate unsafe memory access. You rather write only memory safe code or end up with fully unsafe codebase where some nasty things (buffer overruns or segfaults) are possible. If somebody needs memory safety - managed languages with GC is the only real option.
Ah, I thought we were talking about isolation for code auditing purposes. If you're concerned about address space isolation, then this other statement is false:
> If somebody needs memory safety - managed languages with
> GC is the only real option
If I'm in Java, I can call C code via JNI that does whatever garbage I want with the memory of the Java program. There's no isolation there; we are thwarted by the need for FFI. Likewise, `unsafe` in Rust is just a reified FFI: it allows you to do things that Rust doesn't allow you to do, but, crucially, `unsafe` blocks in Rust are still much safer than the C code that you'd otherwise be writing. Thus `unsafe` is a mechanism for making Rust programs safer than they otherwise would be, by avoiding the need to call into C.
What is unsafe about using atomic reference counting?
> and unsafe shared memory access in Rust.
That should be provided with a safe interface, or an unsafe interface if calling that code is not safe.
As for it being common: I think they are working on minimizing the need for unsafe code.
> This defeats the purpose of this complexity.
Like having a VM implemented in C defeats the purpose of the VM for that language being safe. No, not really - that C code has to be really vetted, just like unsafe code in Rust has to be really vetted.
I guess we might - eventually - be able to formally verify a language implementation, thus really proving that a language is safe (that goes for those managed languages, too). Maybe that will be feasible in a few decades, if ever. Alternatively, you can use the ATS language, where you can prove that unsafe usage of pointers etc. really is being used in a safe way.
> You can't isolate unsafe memory access.
Sure you can - owned and borrowed pointers in Rust are represented as raw pointers at runtime. It's a safe abstraction. And if there turns out to be a bug in that interface, and they aren't really safe, then that will have to be fixed promptly - unlike in C/++, where one would be forced to say "Well, that's your fault for not being careful".
> What is unsafe about using atomic reference counting?
Nothing at all. But sharing objects between threads is unsafe.
> Like having a VM implemented in C defeats the purpose of the VM for that language being safe.
You can prove that VM code is memory safe? Good for you.
> Sure you can - owned and borrowed pointers in Rust are represented as raw pointers at runtime. It's a safe abstraction. And if there turns out to be a bug in that interface, and they aren't really safe, then that will have to be fixed promptly - unlike in C/++, where one would be forced to say "Well, that's your fault for not being careful".
And in C++ we have value and move semantics. Nobody uses pointer arithmetic to implement arrays and strings anymore. std::unique_ptr is a standard way to implement the same semantics as borrowed pointers in rust. Array access can be range checked if you want. So being careful in C++ is easy today, can I say that C++ is safe? :)
> Nothing at all. But sharing objects between threads is
> unsafe.
This is mistaken, as sharing immutable data between threads is trivially safe, and Rust's type system gives you the tools you need to prove that data is actually immutable (good luck sticking anything in an Arc if it contains an Rc (or any other non-Send type) anywhere within it). And sharing mutable data between threads can be safe if you get the locking right: Rust gets the locking right for you, so that you don't have to.
> std::unique_ptr is a standard way to implement the same
> semantics as borrowed pointers in rust
No, std::unique_ptr is analogous to the Box smart pointer in Rust, except more onerous to use because move semantics are not the default in C++. C++ has no equivalent to Rust's borrowed references.
> So being careful in C++ is easy today, can I say that
> C++ is safe?
Sure, if you're willing to throw out all C++ code written before C++11, and if you're willing to lower your standards of "safety" to "trivially, silently, and often surprisingly unsafe". :) I actually have a higher opinion of C++ than most developers you'll find (PHP too, but that's a different story...), but let's not pretend that safety is at all C++'s forte.
C++ is unsafe by default. You have to opt-in to obtain all of the safety (by adhering to a particular pattern of use, or using a particular kind of class, etc.).
Rust is safe by default. You have to opt-out to head into dangerous territory.
That difference may be trivial to some, but to me, it's enormous.
> Nothing at all. But sharing objects between threads is unsafe.
If sharing stuff between threads in Rust is unsafe, then that is a bug which you should report.
> You can prove that VM code is memory safe? Good for you.
Uh, that's my point... VM implementations are usually not proved to be safe, any more than unsafe code in Rust is proved to be safe.
> And in C++ we have value and move semantics.
Which aren't bulletproof - if you're not careful, they can be used in an unsafe way. Well, this is second-hand information, so take that for what you will. You could ask pcwalton about it if you want a truly informed opinion.
> So being careful in C++ is easy today, can I say that C++ is safe? :)
Sure you can. You can say, "My code is safe, because I only use feature X, Y, Z / because I avoid this and that...". While someone using Rust should be able to say "My library is safe, since I make no use of unsafe blocks".
> There are no silver bullets with regards to safety in C/++ code; in order to achieve security, the programmer has to pay the price of being forever vigilant.
A lot of the complexity of Rust is for eliminating security pitfalls which are inherent in C/++.