Presumably, the C++ wrappers suggested here would not even be safe in that sense. They would use a lot of pointers, and cause UB if passed the wrong one. The article argues that using unsafe correctly is impractical for Chromium because basically every Rust function would have to be marked unsafe to call into these raw C++ APIs.
Whether that’s the right call, I don’t know. I see the practical argument, but I also think that a lot of common Rust idioms, especially around memory management, depend on these safety guarantees. For example, field destruction order in Rust is weird and you often don’t control it as carefully as you would in C++. That’s usually fine in normal Rust code, but might not be if lots of marked-as-safe-but-actually-unsafe code is flying around.
This is well-defined, as being dropped in the order that they are declared.
Yeah, the fact that it's the opposite in C++ was a huge point of contention before we defined it; changing what was there risked breaking a lot of code, and there are good reasons for either order. But yeah, I had to go and look at the RFC for exactly the reasons you state; it just isn't normal to care about this at all, so it's easy to not remember.
Don't you just define a destructor[1] and make it explicit? Or maybe I'm missing something subtle here?
Yes, because "safety" in English is not analogous to "unsafe" in Rust in any real manner. They are linked only in the loosest conceptual way. Rust's "safety" and "unsafe" are well defined and exact, and can be objectively determined. In the English language it is by its nature subjective.
> The usual understanding is that an unsafe function is any function that can, if passed the wrong arguments, cause Undefined Behavior.
That is, specifically AFAIK, not what it means in Rust. It's well defined there, so there's no need to resort to "the usual understanding". This causes a lot of confusion, but it doesn't need to. If someone is talking about the unsafe keyword in Rust, they're talking about Rust's definition of it and what it entails, or they're using incorrect terminology.
> Presumably, the C++ wrappers suggested here would not even be safe in that sense. They would use a lot of pointers, and cause UB if passed the wrong one.
Then there's not a lot of point in using Rust if they refuse to change that usage. It's not about using Rust to check off a box that you use some buzzword technology, it's about leveraging what it can provide that other languages can't, or can't do as well.
If someone finally decides to put a firewall in front of a server but decides its' too hard to actually limit traffic in any way so allows 0.0.0.0/0 any port, you don't congratulate them on their firewall, you tell them they just wasted everyone's time and money.
> The article argues that using unsafe correctly is impractical for Chromium because basically every Rust function would have to be marked unsafe to call into these raw C++ APIs.
To my knowledge, the way Firefox did it was to pick a system or library, provide a Rust replacement that C/C++ could call, and allow it to be moved into place. That's sane. Using rust and C++ functions on the same memory and expecting Rust to deal with C++'s pointer shenanigans may not be, in the same way I wouldn't expect mixing small amounts of Java in the JVM into a big C++ would just work unless you had hard rules about who controlled what memory/objects and made sure you never broke them.
I can't help but feel they're approach is likely to cause them more problems than needed because they're not willing to commit the sane minimal amount to make a lot of these problems not matter (replace a small self contained system). If they don't actually have any small self contained system, and they really are just passing stuff around and using some complex pointer control, and aren't willing to change that, maybe Rust isn't a good candidate to extend their project languages with.
I'd say that Rust is using incorrect terminology, since it is at loggerheads with "the usual understanding" (which should be the default, not something "resorted to"). Rust could have chosen a different word than safe/un-safe, but they didn't.
Languages get to define their own terms. It's not rare for two languages to use terminology in similar, but different in fundamental ways, concepts. An extremely common example would be "threads".
In the case of "unsafe", we're not even really staying within the realm of software engineering to find a terminology mismatch in this case, we're going back to the English language itself (in which case almost all the keywords in any language might have a similar problem).
Oh... no, no, that's... very unsafe lol.
Jokes aside, making that their #1 goal was very strange. Agreed it appears to be a fundamental misunderstanding of what "unsafe" means. It doesn't mean that it's literally not safe to call that function, just that it's unchecked. "unchecked" might be a better annotation come to think of it.
Yeah, it's come up before in discussions here. Depending on the context you're coming from/working in, unchecked either makes more sense, or less sense than unsafe. When working within Rust, unsafe makes sense, it maps to how people think about what they are doing, because rustc is checking everything. When working between Rust and other languages/libraries, it's a bit less accurate, and "unchecked" makes more sense.
“We are happy to empower our younger colleagues. We only ask they have 25 years of experience.”
Isn't that what they did? Through the use of https://github.com/dtolnay/cxx
Agreed the article expressed the concern in a rather clumsy manner, but they seem to have a point for their particular use case, and they addressed it appropriately.
I'm not sure whether it's actually better to abstract all the unsafe away, or force it to shown where it's used. In one respect, they may be right, it might lesson the impact of unsafe and it gets used more freely. On the other, it also means that it's not necessarily immediately obvious when you're crossing boundaries, since the obvious bits and intentionally hidden away.
Though I'll freely admit my initial responses were a bit hyperbolic and... testy. :)
There would need to be domain understanding baked into each wrapper and some contract about what is happening on the other side of the ffi wall for it to qualify as both safe and sane, and I’m not sure their approach meets that high burden.
Yeah you can mentally substitute 'rustc_cannot_vouch_for' but why can't Rust use a word closer in meaning to that in the first place?
We tend to misuse everyday meanings I think. I reminded of
1. the msdos warning that 'this program has used an illegal instruction and will be shut down'
2. That DNS names with underscore are 'illegal'. This one caused an amusing kerfuffle at one company I worked at.
3. That certain crypto algos are 'broken'
"safe" is entirely relative in it's everyday meaning. To one person skydiving is safe, to another it is extremely unsafe. When you're a child your parent will tell you what is safe or not, but what your parent considers safe is based on their personal definition of safety.
The rust language will tell you if what you've done is safe based on its very well defined criteria for what that is, and won't let you proceed with something that doesn't match that criteria unless you vouch for it yourself. unsafe makes just as much sense here as any other word, it only seems a wrong fit when you look at it from a context it's not meant to be used in.
This is inevitable. We either invent new words, or we use existing words from the natural language. The latter will always lead to confusion at some point, because the domain-specific concept doesn't exist in the rest of the world. To represent such a concept, a word would need to deviate from its everyday usage.
I think Rust's "unsafe" is an okay choice; the "vouching" is a feature about memory safety after all.
I think the use of "unsafe" is exactly what is a common case. That is declaring, "I know what I am doing," and that for most people do do this may be a bad idea.
> For a Rustacean, this is controversial - all C++ is unsafe!
Isn't this just a fundamental misunderstanding of what unsafe really means, and as such a nonsense goal that doesn't gain anything?
Unsafe is a Rust language definition, and defines whether the rust compiler can vouch for the safety of some code. As such, calling to a library in some other language will always be unsafe, by definition, because the Rust language cannot vouch for it.
If it makes you feel better, replace "unsafe" in your head (or with a macro) with "rustc_cannot_vouch_for" and carry on with your day. It means the same thing, and isn't really telling you that your C++ code sucks even if it looks like it at first glance, so who cares?
If you really want to reduce the unsafe keyword from being seen in most regular code, you create and interface that maps the C++ function and exposes it as a rust function, and you've hidden away your unsafe usage to one spot per function. If you have enough confidence in your C++ code, there's no downside to this (and if you don't, then maybe you shouldn't be complaining that unsafe is unneeded).