9 ms·
Rust is easy to understand as "a language by browser writers for writing browsers." That statement alone gives you most of Rust's design choices: * Safety over
by pclmulqdq 2y ago
Rust is easy to understand as "a language by browser writers for writing browsers." That statement alone gives you most of Rust's design choices:
* Safety over everything else
* Very good single threaded performance
* Javascript-like syntax and a Javascript-like package manager
I have been working on some software in Rust recently that needs bit and byte manipulation, and we have "unsafe" everywhere and hugely complicated spaghetti compared to the equivalent code in C.
- 1932812267 2y agoI love your username, btw :)
- pjmlp 2y agoMost likely because many keep forgetting that bit and byte manipulation in C is a mix of implementation defined and UB, depending on how it is coded.
- motorest 2y agoWhat's the problem of using toolchain-specific features instead of behavior defined by the standard? Isn't this the bread and butter of embedded development and the reason why some behavior is purposely left undefined in the standard?
- eru 2y ago> [...] and the reason why some behavior is purposely left undefined in the standard? It's one of the saner reasons why there's UB in C and C++. But there's lots of crazier reasons.
- motorest 2y ago> It's one of the saner reasons why there's UB in C and C++. It is the reason why the standard purposely leaves some areas undefined. C and C++ detractors talk a lot about UB but they always show their understanding on the subject is at best superficial. The parrot UB as if it was this major gotcha, when it is literally behavior the standardization committees make a call to not define behavior to purposely leave it open, so that any implementation can still be conforming even if they decide to implement behavior not defined in the standard. It is that simple, but somehow people parrot UB behavior as if it was this major gotcha. Baffling.
- pjmlp 2y agoBaffling is the ignorance in the ways of WG14 and WG21, while pretending to be a know it all, maybe update yourself on the relevant papers for C2y and C++26, aimed at clearing up references to UB with erranous behaviour, or implementation defined.
- formerly_proven 2y agoThis subthread is kinda strange with people claiming IB and UB are the same, considering that C/C++ have had clearly delineated definitions of undefined behavior versus implementation-defined behavior for decades in their term definitions.
- grandempire 2y agoNo, we do understand the difference and the comment still stands. UB is a choice by the standard committee. Signed integer overflow is undefined because it’s not even clear if you can detect it happens in all implementations. Do you want a conditional after every integer add?
- eru 2y ago> Signed integer overflow is undefined because it’s not even clear if you can detect it happens in all implementations. Do you want a conditional after every integer add? Huh? You can just make it implementation defined, and most implementations would declare it to work like twos-complement wrap-around. Just like unsigned integer overflow is already defined in the standard. Where does the conditional you are talking about come from? Unsigned integer overflow doesn't have any conditionals either. Compilers like GCC already support wrap-around for signed integers with a command line option. It's spelled "-fwrapv", and I don't think it involves any conditionals.
- grandempire 2y ago> You can just make it implementation defined No you can't. Let me repeat again. One very possible implementation is to crash on signed integer overflow (`-ftrapv`). But if it cannot easily detect it, then it must either: a) check every integer add. b) use some less reliable detection method (random sampling, etc). To be well defined means the implementation will reliably do the same thing. A procedure which sometimes does one thing or another, is not well defined. > Unsigned integer overflow doesn't have any conditionals either. That's because there is no detection needed. The instruction set for unsigned integers is designed to do that. > -fwrapv Here is the documentation: > This option instructs the compiler to assume that signed arithmetic overflow of addition, subtraction and multiplication wraps around using twos-complement representation. https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html What this means is that if your hardware wraps on signed integer overflow, you can tell GCC that you are perfectly happy with that behavior. Then GCC understands and will handle it just fine. If your hardware does something else, `fwrapv` will not help you.
- pjmlp 2y agoSecurity exploits is the problem, because what common people that don't read WG14 mailings think the word undefined means, and what everyone else involved with creating compilers understand what they are allowed to do, is not the same.
- motorest 2y ago> Security exploits is the problem, because what common people that don't read WG14 mailings think the word undefined means, and what everyone else involved with creating compilers understand what they are allowed to do, is not the same. Your comment lacks credibility. Your hypothetical scenario would only be conceivable if a) a team was well versed enough in C to adopt a specific toolchain to leverage implementetion-defined behavior that leveraged behavior left undefined by the C standard, b) somehow the same team decides on a whim to replace their toolset with some other random toolset without eve being aware of their toolset-specific code. This is far from a realistic scenario, and reads more like mindless complains about UB coming from a place of ignorance.
- pjmlp 2y agoCVE database, the ongoing liability laws in cybersecurity across several nations, and companies that also happen to be C and C++ compiler vendors, are my credibility. It is incredible how for the last 50 years we keep getting ad-hominens from folks that think actually to know anything at all about security, and only clueless junior developers don't know what they are doing.
- pclmulqdq 2y agoExactly this. Most of the art of it is avoiding UB and sticking to implementation-defined behavior.
- pcwalton 2y ago> I have been working on some software in Rust recently that needs bit and byte manipulation, and we have "unsafe" everywhere and hugely complicated spaghetti compared to the equivalent code in C. I'm curious what makes this so different from my experience. I rarely ever have to write "unsafe", and I'm writing quite low-level engine code that certainly uses bit manipulation. In fact, crates like bitflags and fixedbitset make it so easy that I tend to get dinged in code reviews for using bit flags when structs of booleans would be simpler :)
- eru 2y ago> I'm curious what makes this so different from my experience. I rarely ever have to write "unsafe", and I'm writing quite low-level engine code that certainly uses bit manipulation. Perhaps your usecase is similar enough to eg JavaScript engines? Because that's a usecase that browser writers would at least have in mind?
- Ygg2 2y agoIt's not. It's Bevy. What effects this is separating your unsafe into unsafe abstractions. If you're careful you don't have to write too much unsafe. Granted it's not easy.
- pclmulqdq 2y agoA game engine is much more similar to a browser engine than you think. The operations you have discussed, using bits as flags, are also the most basic forms of binary-level manipulation out there. Things like tagged pointers and bit flags fit nicely and neatly into an encapsulated unsafe abstraction (provided you want to add an extra 1000 lines of code for it). As far as I can tell, any time you want to rely on the exact binary layout of something in memory, you need unsafe. As a corollary, any time you want to bit cast from one type to another, you need unsafe. This means that things like succinct data structures and building network protocols need quite a bit of unsafe everywhere. The former needs you to do things like "store 14 bits of X here and 12 bits there..." The latter needs control of bit and byte layout because you want to carefully eliminate implementation-defined compiler behavior.
- motorest 2y ago> * Javascript-like syntax and a Javascript-like package manager I think this is not serious criticism. The "javascript-like package manager" reference actually refers to fixing a major problem with the developer experience playing legacy programming languages such as C or C++. Java has those, .NET has those, every single mainstream programming language has those. Except C or C++. Rust might be riddled with "the emperor has no clothes" aspects, but having a package manager is not it.
- pclmulqdq 2y agoThat's not a negative aspect of Rust, and I'm not picking out a list of things I dislike about Rust. Making a statement that isn't unequivocally positive does not equal criticizing something. Cargo is, however, a similarity with JS. On the whole a good one. Also, cargo works much more like npm than maven, for example.
- pornel 2y agoCargo has been co-created by Yehuda Katz, who worked on Ruby's Bundler before. Cargo has been designed after npm, so it definitely took lessons from it, but it doesn't make sense to just broadly attribute this to Rust being JavaScript-adjacent. The Rust syntax is not coming from JavaScript. It even has conflict with it, using `let` and `const` differently, since the `let` in Rust comes from Ocaml, not JS. Both JS and Rust copy from the same C/C++ roots. Rust's curly brace flavor is more similar to Go and Swift. The original author of Rust liked a lot of languages with different syntaxes, but the C-like syntax has been a pragmatic choice to avoid putting off the target audience of C++ programmers: http://venge.net/graydon/talks/intro-talk-2.pdf http://venge.net/graydon/talks/intro-talk-2.pdf
- deleted 2y ago[deleted]