6 ms·
>> So I'm not sure how this can really improve the state of things compared to C with the equivalent bounds checks. [emphasis added] Like all things Rust, you
by phkahler 3y ago
>> So I'm not sure how this can really improve the state of things compared to C with the equivalent bounds checks. [emphasis added]
Like all things Rust, you can do the same thing in C but that requires extra effort and more source code. If Rust will add bounds checking for you automatically, that's a step up from C.
- bayindirh 3y agoIf you don't need to do bounds checking, and doing it anyway, then that's a step down from C.
- mcfedr 3y agoBut isn't the point that the number of times a c programmer thought they didn't need bounds checks and reality are very different. Also off by one errors and such. Rust won't let you make these mistakes
- bayindirh 3y agoI personally don't think that a programming language should save me from myself unless I explicitly ask for it. For every case I first prove to myself that I can get away without bounds checking, otherwise if I'm in doubt, I put it in and profile. I think Rust is a nice language, but when it's presented as an "antidote" to "evils of C/C++", and is "indeed made to kill those" I lose my interest. Also, while I think learning Rust is worthwhile, I think promoting Rust's barriers as saviors are funny. We say that Apple's against general purpose computing with all its walled gardens. Then Rust is against "General purpose programming". I want to be able to write programs which crash and burn like meteors entering the atmosphere, because this allows me to understand the hardware under me. Promoting a walled programming language as "the one and only" is wrong. Why should I embrace a programming language as one and only if that doesn't allow me to do what I want with my computer? Edit: No, unsafe doesn't count, because it doesn't remove all checks.
- chatmasta 3y ago> Edit: No, unsafe doesn't count Why not? You can basically write C with FFI and unsafe. In fact that's how many "port to Rust" projects start. It seems directly analogous to the fact that you can disable SIP on macOS to escape their walled garden, into an "I know what I'm doing" mode.
- pjc50 3y agoMemory safety has become important enough to be a matter of national security: https://www.whitehouse.gov/oncd/briefing-room/2024/02/26/press-release-technical-report/ https://www.whitehouse.gov/oncd/briefing-room/2024/02/26/pre... > I want to be able to write programs which crash and burn like meteors entering the atmosphere Sure, fine, whatever, just as long as it's not used by anyone else. Production code needs to be held to standards.
- bayindirh 3y agoI'm a big proponent of choosing the right tool for the job at hand. On the other hand, I'm a big opponent of throwing stones because of emotions. C/C++ can be made memory safe. You need to use a couple of data structures and need to be a little bit more vigilant and make periodic tests. If the developers can't bother to learn them, that's fine. However, saying something is impossible and being adamant about that without research is harmful as it is. I sometimes say things about Rust, people correct me, and I learn. Some people see the evidence contrary to their beliefs and get triggered because they were wrong in the first place. This is what I'm bothered about. I don't use C or C++ only. I'm not against Rust either. I'm against positioning of Rust and C/C++ from Rust community's perspective. That's all. Lastly, I'm not a proponent of reckless coding either. Totally contrary. I take pride in writing robust code. However, I want to be able to write code which breaks on purpose to see what hardware does, to understand the failure modes or gotchas of the architecture I'm running on.
- jeroenhd 3y agoVery little Rust code actually does all the safety checks that you would expect a debug build of that same program to do, especially in the kernel. You can write safe rust (check the Option<T> returned by vec.get(i)) but code like `p[0] = update_prob(d[0].into(), p[0].into()) as u8;` (https://gitlab.collabora.com/dwlsalmeida/for-upstream/-/commit/7681609641fb9c94a0b5d827dc2e7290401689c3#eef62635f4a18e96131ace643dc5dcb1dde2fbb5_0_1645 https://gitlab.collabora.com/dwlsalmeida/for-upstream/-/comm...) can panic at three different places. Such a panic would become a kernel oops, which wouldn't be the end of the world but it would probably kill whatever program was trying to decode video. With additional optimisation options, the bounds checking may even be omitted entirely. Rust does generate more accurate bounds checking warnings thanks to all the metadata it has, but that should not be solely relied upon. Rust will let you make those mistakes, but only sometimes, not usually like in old C or C++. I think it's important to know the difference, because feeling invulnerable to these bugs may lead you to write buggy code because you stopped thinking about common C bugs entirely. Also worthy of note is that because of a compiler bug, it's possible to leak memory and cause other weird memory bugs in perfectly safe Rust at the moment. It involves messing with lifetimes and semi-unsafe code so I doubt that bug would just sneak in, but the language doesn't make your code completely bullet proof.
- KerrAvon 3y ago> can panic at three different places Remember that some of the point here is that it _will_ reliably kill the program if that happens; in C, you might be silently reading or writing to the wrong address 3 times.
- Mateon1 3y agoThe `single_ref` field is a fixed-size array in both of the objects referenced in this line, so this line can't panic, and no bounds checks are involved (since the compiler sees the index < length at compile time and doesn't even need to emit one -- although I think it still does, and it's LLVM that gets rid of it actually) Causing memory leaks is possible in safe Rust even without any arcane invocations, you can construct a cycle of Rc<T> counted objects. There's even a perfectly safe Box::leak in the standard library that gives you a &'static reference to any object by leaking it. Preventing leaks is outside of the scope of Rust's safety system.
- estebank 3y agoIf you can assure that bounds checks are not necessary (either by construction, because it's a statically sized array, or by runtime check because you do a length check once at runtime), then doing those same things will tell rustc enough to know that bounds checks aren't needed[1][2]. If you think you don't need bounds checks, but can't communicate that in code, such as with an assertion (or if rustc had a bug that misses those checks, unlikely but could happen), then yes, you'll end up with bounds checks unless you use get_unchecked in an unsafe block. I'm failing to see how this is an onerous difference. 1: https://nnethercote.github.io/perf-book/bounds-checks.html https://nnethercote.github.io/perf-book/bounds-checks.html 2: https://github.com/Shnatsel/bounds-check-cookbook/ https://github.com/Shnatsel/bounds-check-cookbook/
- Aurornis 3y ago> If you don't need to do bounds checking, and doing it anyway, then that's a step down from C. The Rust compiler tries to optimize away unnecessary bounds checks. In practice, it works well. The real-world cost of Rust bounds checking isn't very significant in most benchmarks, aside from some synthetic micro-benchmarks designed to emphasize the issue. If you come across a hot loop in Rust where bounds checking is an actual overhead, you can manually optimize it out if you so desire. It's important to really check first, though, because it's often surprising that it makes such little difference or has been optimized out already.
- jcranmer 3y agoWho would you rather trust to do bounds checking, computers who are zealously good at doing what they are told to do to the point of absurdity or humans who are notoriously bad at following rigorous procedures? I mean, we've seen from several other fields that the only way to get the safety standards of human procedures up is to introduce checklists and get people to rigorously follow them [1]. If you want to elide bounds checks for performance reasons, which is easier: manually verifying for yourself that every single array access is guarded by a bounds check somewhere and ensuring that no subsequent code changes break this verification, or getting the compiler to prove for you that every bounds check can be safely elided? [1] And of course we still have several issues in fields like medicine where practitioners refuse to adopt this methodology because they find checklists to be an insult to their intelligence.
- bayindirh 3y ago> getting the compiler to prove for you that every bounds check can be safely elided? I'd prefer to delegate that where compiler if it can do that for that piece of code at hand. I've written about a case where it'd be very hard for a compiler to eliminate a bounds check because the guarantees are made elsewhere in the code. On the other hand, I'd rather add my bounds check voluntarily (it's very simple in C++ vectors for example. use ".at()" instead of "[]", that's all), because I generally design my code in a way which doesn't need bounds checks by failing hard and early at places where I build/fill the arrays/vectors and prone to malformation. So, you need to be well-formed to pass these checks, and these data structures are not modified ever down the pipe. If they are modified, they'll be bound checked of course. What I'm saying is, I'm not naive enough to believe that I'm perfect, but I'm not naive enough to believe that compiler is perfect, either. So, I do my part, and leave the parts I can't be sure to the compiler. I'm not an hard-liner. I just want finer control on my code, and take full responsibility if it crashes and burns in a way it shouldn't, so plan and implement accordingly.