And miri is a blessing. There even is a known case where someone found a bug in C by translating it to rust and then running it through miri.
What on Earth do you mean?
Getting people to adopt a new language can be a lot of work. I remember people claiming they missed headers files in Swift so they wanted to stick with Objective C.
That documented use of safe Rust can easily lead to UB, which this infernal 'internal compiler representation' demonstrates.
I'm not even sure what is even remotely confusing about that?
> ... detect unsafe code that fails ...
Show me the documented safe Rust code that causes UB without using any unsafe blocks outside of the standard library.
So, the reason I posted my original reply, is that at one of my $DAYJOBs, we recently had a 3-day outage on some service, related to Rust. Something like using AVX to read, like, up to 7 bytes too many from an array.
Nothing really major -- we have a 10-day backup window, and the damage was limited to 4 days, so we were able to identify and fix all identified cases. But the person-to-Git-blame for this issue happened to be one of my mentees, and... they were blown away by it.
As in: literally heartbroken. Unable to talk about it. "But the compiler said it was okay!", crying. One of my coworkers pointed at MIRI, which correctly warned about the issue-at-hand, at which point I recommended incorporating that tool into the build pipeline, as well as (the usual advice in cases such as this) improving unit tests and focusing on X-1 and X+1 cases that might be problematic.
To this day, I'm truly worried about my mentee. I'm just a C# wagie, and I fully accept that my code, my language, my compiler, and my runtime environment are all shit.
But, as evidenced by my experience and supported by the voting in this thread, it seems that Rust users seem to self-identify with the absolute infallibility of anything relate to the language, and react quite violently and self-destructively to any evidence to the contrary.
As a community leader, do you see any room for improvement there? And if not, what would it take to convince you?
Conversely, if you never encounter bugs in a component, it means it's not being improved fast enough.
This would require using unsafe code.
> As in: literally heartbroken. Unable to talk about it.
I would hope that this person improves as an engineer, because this isn't particularly professional behavior, from the way you describe it.
> "But the compiler said it was okay!"
Given that you'd have to use unsafe to do this, the compiler can't say it was okay. It sounds like this person may not fully understand Rust either.
> it seems that Rust users seem to self-identify with the absolute infallibility of anything relate to the language, and react quite violently and self-destructively to any evidence to the contrary.
I don't see how this generalizes. You had one (apparently junior, given "mentee"?) person make a mistake and respond poorly to feedback. You also barged into this thread and made incorrect statements about Rust, and were downvoted for it. That doesn't mean that Rust users think everything is perfect.
> As a community leader, do you see any room for improvement there?
I do think sometimes enthusiastic people who don't understand things misrepresent the thing they're enthusiastic about, but that's a human problem, not a Rust problem. I do not think there's a way to fix that, no.
I think the story is just somebody who didn't actually learn unsafe Rust properly (and I'm struggling to give it the benefit of the doubt, as it sounds quite exaggerated; I couldn't imagine a novice Rust dev literally crying because they thought unsafe blocks couldn't cause UB. If you were that emotionally attached to the language, I'd expect you to have learned what unsafe means).
Sure, not being able to do basic things like IO might be a bit of a limitation at first, but, that's all worth it, I guess?
Again: I'm pointing out to you that your absolutist stance on 'unsafe' and 'UB' is doing more harm than good.
You continue to choose to ignore this, which is your right. But as a "community leader" you could and should to better. As could I, I guess, by simply ignoring you, but, the mental health issues I see you cause in real-life make that sort-of hard...
The points are:
* Unsafe Rust is required to uphold specific guarantees to not cause undefined behavior. This can be tricky, but it's not impossible, it just involves a lot of care and some tooling like Miri for those specific situations. The situation is the same as pretty much the entirety of the C and C++ languages, plus Rust reference safety.
* Safe Rust is designed to not cause any UB on its own. It can only "bleed" UB from incorrect unsafe code. Without any incorrect unsafe code, this is easy to work with and involves much less work and care.
* Therefore, keeping your unsafe blocks small and in dedicated crates where they can be individually tested increases the quality and reliability of the codebase.
Surely you can see that it's an improvement over the previous status quo. I don't know what absolutist stance you're talking about. Most Rust fans I know, including myself, accept that Rust is an imperfect language, representing an improvement over C and C++. It's not just hypothetical either. Rust has brought demonstrated improvement in reliability for us, and for some of the biggest companies in the world who now lean on it to reduce their rate of defects.
* like un-unified representation of nullable reference types and structs under generics for example, or just the weight of features over the years, still makes most other alternatives look abysmal in comparison
What is shit about those things for C#? That’s the application programming language that seems to get the least flak out of all of them.
If I’m using an alpha or beta compiler, I might suspect a compiler bug from time to time… not really when I’m working in a decades-old, very established language.
So they fixed the biggest issues (at least it has value types), but it has nullable classes, collection types are mutable, integer overflow doesn't trap, it doesn't have nearly enough program verification features (aka dependent types), etc.
Worst of all it was written by enterprise programmers, who think programs get better designed when you put all their types four namespaces deep. I assume whoever named System.Collections.ArrayList keeps everything in their house in one of those filing cabinets with the tiny drawers.
Those are bugs. They are faults in the code. They need to be fixed. They are not UB-as-a-feature like in C/C++. “Well watch out for those traps every time you use this.”
This is like getting mad that a programming language boasts that it produces great binaries and yet the compiler has a test suite to catch bugs in the emitted assembly. That’s literally what you are doing.
Rust has UB-as-a-feature too. They could have eliminated UB from the language entirely, but they chose not to (for very valid reasons in my opinion).
UB is a set of contracts that you as the author agree to never violate. In return, you get faster code under the assumption that you never actually encounter a UB condition. If you violate those contracts in Rust and actually encounter UB, that's a a bug, that's a fault in the code. If you violate those contracts in C++, that's a bug, that's a fault in the code. This is the same in both languages.
It's true that Rust UB can only arise from unsafe blocks, but it is not limited to unsafe blocks. Rust UB has "spooky action at a distance" the same way C++ UB does. In other words, you can write UB free code in Rust, but if any third party code encounters UB (including the standard library), your safe code is now potentially infected by UB as well. This is also the same in both languages.
There are good reasons to favor Rust's flavor of UB over C++'s, but I keep seeing these same incorrect arguments getting repeated everywhere, which is frustrating.
Tell me what I wrote that was incorrect. I called them UB bugs in the standard library. If they were trivial bugs that caused some defined-behavior logic bug while used outside of the standard library then it wouldn’t rise to the level of being called an UB bug.
That's the part that's incorrect. That, plus the implication that UB is a bug in Rust, but not in C++. As I said, the existence of UB is a feature in both languages and actually encountering UB is a bug in both languages. You can play with the semantics of the word "feature" but I don't think it's possible to find a definition that captures C++ UB and excludes Rust UB without falling into a double standard. Unfortunately double standards on UB are pretty common in conversations about C++ and Rust.
Do you think UB-as-feature is something that someone would honestly describe C or C++ as? It’s a pretty demeaning way of framing things. Indeed it’s a tongue-in-cheek remark, a vhimsical exaggeration/description of the by-default UB of those languages which was added to the end of the completely factual description of the role that finding UB in the Safe Rust subset of the standard library of Rust serves.
Of course one cannot, from the Rust Side so to speak, use tongue in cheek, off-hand remarks in these discussions; one must painstakingly add footnotes and caveats, list and mention every trivial fact like “you can get UB in unsafe blocks”[1] or else you have a “double standard”.
[1] Obligatory footnote: even though all participants in the discussion clearly knows this already.
Yes. That's how I describe it. That's also how Ralf Jung (long time Rust contributor and one of the main people behind Miri) describes UB in both Rust and C++ (although he says C++ overdoes it) [1]
The thing I edited out of my comment was "motte and bailey fallacy" because after reflecting a bit I thought it was unfair. But now you're actually trying to retroactively reframe as a joke.
[1] https://blog.sigplan.org/2021/11/18/undefined-behavior-deser...
Okay. Then I was wrong about that.
> The thing I edited out of my comment was "motte and bailey fallacy" because after reflecting a bit I thought it was unfair. But now you're actually trying to retroactively reframe as a joke.
What a coincidence. I had written on a post-it note that you were going to pull out an Internet Fallacy. (I guess it’s more about rhetoric.)
I guess you’ve never seen someone explain after the fact that they were being tongue in cheek (it’s not a joke, it’s an exaggeration)? Because jokes, sarcastic remarks are always clearly labelled and unambiguous? Okay then. I guess it was a Motte and Bailey.
This is correct, and it's hard to teach, and I agree that a lot of folks get it wrong. (Here's my attempt: https://jacko.io/safety_and_soundness.html.) But I think this comment is understating how big of a difference this makes:
1. Rust has a large, powerful safe subset, which includes lots of real-world programs. Unsafe code is an advanced topic, and beginners don't need to learn about it to start getting their work done. Beginners can contribute to big projects without touching the unsafe parts (as you clarified, that means the module privacy boundaries that include unsafe code, not just the unsafe blocks), and reviewers don't need to be paranoid about every line.
2. A lot of real-world unsafe Rust is easy to audit, because you can grep for `unsafe` in a big codebase and zoom right to the parts you need to look at. Again, as you pointed out, those blocks might not be the whole story, and you do need to read what they're doing to see how much code they "infect". But an experienced Rust programmer can audit a well-written codebase in minutes. It's not always that smooth of course, but it's a totally different world that that's even possible.
The only thing that comes to mind that this could be referring to are the open bugs at https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Ais.... Are these what you're referring to?
> this infernal 'internal compiler representation'
What makes MIR "infernal"?
> I'm not even sure what is even remotely confusing about that?
You posted a link to a tool that executes pure rust libraries and evaluates memory accesses (both from safe and unsafe rust code) to assert whether they conform to the rust memory model. It sits in the same space as valgrind. You left it open to interpretation with really no other context. We can be excused for not knowing what you were trying to say. I personally still don't.
Would you mind explaining to a dev that doesn’t know much (anything) about Rust, how does this settle any debate?
It's a concatenation of several logical fallacies in a row; equivocation, straw manning, binary thinking about safety, several others. It's hard to pick the main one, but I'd go with the dominant problem being a serious case of binary thinking about what "safety" is. Of course, if the commentor is using anything other than Idris for all their programming, they're probably not actually acting on their own accusations.
I'm sure the Idris compiler has bugs somewhere too. If the OP actually programs, they are violating their rationale (I'm quite sure assembly or assembled binary aren't ok either).
From the Miri github: > Miri is an Undefined Behavior detection tool for Rust.
> The preferred approach is to use “safe” programming languages
“Safe”. Terms and conditions may apply.
In other words, from "safer languages are necessary" it does not follow that "safer languages are sufficient".
Yet, the linked repository shows a huge list of cases in which simple, documented use of Rust can cause Undefined Behavior (a.k.a. 'UB')
Pretty much every argument of Rust advocates against C/C++ boils down to either 'but memory safety' or 'but UB'.
Yet there are many convincing counter-arguments that boil down to 'but CompCert' or similar, and, as the linked repository shows, there might be at least some truth in there?
Also, many people cite things like Cargo as a reason to prefer Rust over C and C++, as well as other things. UB is a big part of it, of course, but it isn’t the only thing.
No, but there are a lot of people claiming that Rust cannot ever have any problems.
Just look at this thread. I merely linked to MIRI, and am currently at, like, -10 just for that.
Lots of people claiming that it just applies to 'unsafe Rust': is that true or not?
Regardless of anything else: can you, as a Rust community leader, please state clearly: is UB in generally safe Rust possible or not?
UB is not possible in safe Rust, by design. The root cause of UB is always in unsafe code. Miri is useless if your code is 100% safe Rust.
The only exception to this is bugs in the compiler, of which there are a few. They’ll be fixed.
You're available as an expert witness to that fact?
Because, eh, well, in at least one of the Rust-related situations that I'm involved in right now, someone might soon very well require the services of a person both as wise and reluctant-to-offer-any-kind-of-compromise as yourself...
In any case, I'm truly done here, in all senses of the word, but I still I wish you and your acolytes the absolute best.
Let me be even more explicit than steveklabnik here. If your code, including any libraries you link to, is 100% Rust and free of any unsafe blocks, then (barring compiler bugs) it is impossible to execute undefined behavior. If your code has an unsafe block, then it is possible execute undefined behavior. Note that it is possible for safe code to execute undefined behavior, IF there was an unsafe block that did an operation that requires the programmer to promise something was true that was not true.
For example, there is an unsafe method that will let you convert a pointer to a reference with an arbitrary lifetime. If you wrap that in a safe function, you can return a reference to an object whose lifetime has ended, and cause undefined behavior in attempting to use that lifetime--the attempt can even be outside the safe block. But were that unsafe block that upgraded the lifetime not present, then you couldn't cause the later undefined behavior to happen.
In short, an unsafe block is where the compiler can no longer guarantee that the conditions that prevent the ability to observe undefined behavior are present, and it is up to the programmer to ensure that these conditions are met, and even and especially ensure that they continue to be met after the unsafe block completes. I do worry that too many programmers are blasé about the last bit, and it sounds like your coworker may fall into that category. But Rust has always maintained this principle.
a) There is no such consensus. The actual consensus is that even if Rust solved all problems, it would not be financially feasible to rewrite pretty much any substantial project.
b) While Rust does solve many problems, it is nowhere close to solving all safety, otherwise there would be no `unsafe` keyword. Alas, fully proving safety in an impure, turing-complete language is mathematically impossible.
c) The only reason you would think that there's some sort of woke Rust lobby, is if you spend way too much time subjecting yourself to opinions of literal sixteen year olds on twitter.
No, that’s not the consensus. This is a strawman.
This is obvious example of strawman. Why are you doing this?
However, as evidenced by the arguments and voting in this thread, Rust proponents will take no criticism, whatsoever.
I linked to a GitHub repository that documents many, many instances in which generally safe Rust causes UB.
The same kind of UB that recently hit one of my coworkers, caused a 3-day outage and now (despite all my counseling to the contrary!) will burn them out permanently.
My only request: can you guys please back off just a little bit? Programming is already hard enough without the purity wars you're stoking all the time...
how often do we hear something like "C and C++ are horribly flawed and completely unsafe. it's basically a crime against humankind and gross negligence to use them"?
i get weary of that kind of thing too. i wouldn't approach it by reacting in the same way as the GP comment, but i get it. and it's not really that much of a strawman. it's more exasperation and sarcasm.
personally, i'm very interested in rust. but everytime someone at best "overhypes" it or at worse, outright dogs on other languages, it's a negative point toward dealing with the whole rust ecosystem.
I do, however, see people trot out the oft-repeated "rust evangelists want to rewrite everything in rust" or "rust people say programming C++ is a crime against humanity", but it seems to me that's the only place I see this argument. In other words, it's a simple strawman.
People can, in the most neutral way possible, point out facts about how safe or unsafe Rust is compared to C and C++. People will STILL complain about how the Rust zealots are bullying their language. This is how it plays out every time.
You can look at this thread. The “exasperation and sarcasm“ is stupid and one-sided. “But” they always say “that’s just a reaction to a previous debate”–because the Rust zealots are always in the rear-view mirror, never in front of them.
How about complaining about something in Rust… that is bad? Like how un-ergonomic Async is? Or how pointy and awkward the syntax can be? Instead they choose to fight the losing battle over how C and Rust are equally unsafe or how actually Rust’s safety doesn’t matter, depending on the phase of the moon. Then they whine about tone and zealotry when they realize arguing against Rust safety from the C and C++ side is a losing battle and they have run out of arguments.
This does not settle the debate because unsafe is rarely needed for a typical Rust program. In addition, the presence of an unsafe block also alerts the reader that the set of possible errors is greatly increased for that part of the code and more careful auditing is needed.
It’s a little like saying traffic lights are useless because emergency responders need to drive through them sometimes, so we should just leave intersections completely unsignaled and expect drivers to do better.
Rust is by default restrictive and requires you to explicitly make it unsafe, C/++ are by default unsafe and require you to explicitly make them restrictive.