4 ms·
A downstream consumer might not need to use the keyword unsafe, but by calling such a function, they have de facto lost memory safety. It is a nice-to-have to k
by incrudible 5y ago
A downstream consumer might not need to use the keyword unsafe, but by calling such a function, they have de facto lost memory safety. It is a nice-to-have to know that only the unsafe blocks of code are able to violate memory safety, but once memory is corrupted, errors can manifest anywhere.
Rust in practice is likely not as safe an ecosystem as C#, because Rust users are more likely to use unsafe blocks for performance tricks. In my view, Rust should have a safe keyword to mark functions that are transitively not unsafe, much like the pure keyword in some languages marks transitive functional purity.
- lucian1900 5y agoP/Invoke is not uncommon either, especially in Windows. Rust and C# offer similar guarantees.
- eloff 5y ago> A downstream consumer might not need to use the keyword unsafe, but by calling such a function, they have de facto lost memory safety. That's a silly definition of memory safety. You can't write a non trivial rust program that doesn't use unsafe in it's dependencies. No interior mutability, no allocation, no containers. The point is these uses of unsafe are checked by the author to ensure they can't introduce unsound behavior through the exposed safe API. > Rust in practice is likely not as safe an ecosystem as C#, because Rust users are more likely to use unsafe blocks for performance tricks. Sort of agree with you here. Unsafe code is rare in C#. But C# has race conditions so some kinds of bugs are more common. But C# isn't as suited for systems programming type of problems or really high performance code.
- incrudible 5y agoIt is an honest definition of memory safety. The fact that you can not write a non trivial Rust program without unsafe dependencies is not an argument against that definition. Most languages considered memory safe have some sort virtual machine model where non trivial programs can be written without any use of unsafe. The virtual machine implementation itself may be unsafe of course, but that is a pretty solid boundary. In Rust, that boundary is easily crossed by anyone, for any reason, to the point where it sips into 50% of dependencies, as this paper shows. I am not saying that C# evades this issue in principle, obviously it has the same functionality, it is just not used as liberally. Concurrency is orthogonal.
- woodruffw 5y ago> Most languages considered memory safe have some sort virtual machine model where non trivial programs can be written without any use of unsafe. With the obvious exception of JS in the browser, I don’t believe this is true: Python, Ruby, Java, C# all have widely used unsafe native escape hatches that are regularly found in dependency trees. All you have to do is misuse these interfaces, which is significantly easier than in Rust.
- incrudible 5y agoRead carefully: The premise is that you can't write a non-trivial program in Rust without using unsafe. It's true that most language implementations have an escape hatch in the form of a foreign function interface and/or they have native extension modules, nevertheless non-trivial programs can be written without using them. Conversely, using such facilities is often a reason why a program may not be portable between multiple language implementations.
- eloff 5y agoNo, that's not my premise. You can't write a non trivial rust program that doesn't use unsafe in it's dependencies, often the standard library. But this is true of every other programming language I'm aware of. So if you want to define memory safety to be something never achieved in practice, fine, but that's not a useful definition in my books.
- incrudible 5y ago> No, that's not my premise. You can't write a non trivial rust program that doesn't use unsafe in it's dependencies, often the standard library. Same difference, because the use of unsafe is transitive. There is no distinction between "unsafe-but-part-of-the-standard-library" and "unsafe". > But this is true of every other programming language I'm aware of. So if you want to define memory safety to be something never achieved in practice, fine, but that's not a useful definition in my books. I don't. I already made that distinction further up in the thread, you can read that and reply there if you have any objections.
- svat 5y agoWhy would memory get corrupted in this example? To put it differently: if the code didn't have the `if index < array.len()` check, clearly things would be different. How would you describe this distinction, other than "memory safety"? (Asking because it's not clear whether you're using an unusual definition of memory safety, or just didn't notice the bounds check in the example.)
- incrudible 5y agoI am making a general statement about unsafe functions, not the subset of unsafe functions that happen to be memory safe.
- kibwen 5y ago> Rust in practice is likely not as safe an ecosystem as C#, because Rust users are more likely to use unsafe blocks for performance tricks. But this suffers from selection bias: people don't tend to write the same sort of high-performance libraries in C# as they do in Rust precisely because of how much harder it is to squeeze out every last drop of performance from a managed language (even taking into account C#'s own `unsafe` keyword). If Rust didn't offer `unsafe` and only privileged its own first-party constructs then it could certainly produce a more broadly safe ecosystem, but it would not produce a more useful one. And therein lies the whole point: the goal of Rust is not to produce a safe ecosystem for its own sake, but to provide a more reasonably-safe alternative to C and C++ for the sorts of things that C and C++ get used for.
- incrudible 5y agoThat's why I would argue for a "safe" keyword. In this sense, the compiler can actually help me write safe code and encourage library authors to do the same. Either safety really matters and performance can be given up for it, or vice versa. I do not believe that Rust is a "reasonably-safe" alternative to C, because C is already reasonably safe if written with safety in mind, but with the added bonus of being simpler. Rust is reasonably unsafe when written with performance in mind, whereas C++ is just unreasonably unsafe.
- afavour 5y ago> but once memory is corrupted, errors can manifest anywhere Yes, but those errors can only be caused by code flagged with the unsafe keyword. Which makes debugging, auditing etc. a lot more simple than in, say, C, where it could happen anywhere.
- incrudible 5y agoThis isn't necessarily a huge help, because those errors could be triggered or manifest at any point where unsafe code is used transitively. In C, not every single line is unsafe. All that the unsafe keyword ultimately does is to force you to aggregate such lines into blocks with the word "unsafe" around them. You can speculate that this is a significant improvement. I would argue that a disciplined use of a simple language like C would, in practice, be safer than using a complex language like Rust which has "safety" written all over it - but then liberally sprinkles unsafe code into all the gaps. We can both agree that C++ is the worst of both worlds.
- afavour 5y ago> This isn't necessarily a huge help, because those errors could be triggered or manifest at any point where unsafe code is used transitively. Right, and that isn’t something Rust or the unsafe keyword set out to solve. Unsafe has absolutely no runtime impact and was never designed to. Your argument that a disciplined use of C would render this useless is correct, but history has shown us a great many examples of undisciplined use of C, even in projects that start out disciplined. Rust codifies and enforces that discipline, I don’t see anything wrong with that. You want unsafe to be something it isn’t, but I’m not convinced what you want fits with Rust’s vision. There are many, many safer languages to choose from.
- incrudible 5y ago> Rust codifies and enforces that discipline I completely disagree with that. There's no discipline required to slap "unsafe" around a block of code. The discipline must be applied to the block of code itself, there is no way to enforce that. If 30% of dependencies have unsafe code in them, how would I know that the unsafe parts aren't just as sloppily written as the average C code? Rust has yet to prove itself as a language that actually delivers on its promise of being safer than C, in practice. To that end, we must compare C written with security in mind to Rust written with security in mind. Given that Rust is a rather complex language that encourages abstraction, I'm quite hesitant to drink the cool-aid right away.