4 ms·
Some UB in C is largely regarded as a bad idea, such as signed overflow. One reason for that is that it's easy to get rid of it, and guess what, we have a bunc
by obl 8y ago
Some UB in C is largely regarded as a bad idea, such as signed overflow.
One reason for that is that it's easy to get rid of it, and guess what, we have a bunch of compiler flags just for that.
That absolutely does not mean that "UB is bad, period".
In fact you praise Rust but only safe Rust has no UB.
Actually, if they do end up putting more and more knowledge about the type system invariants in the optimizer, the rules for UB in unsafe code are going to be more complicated than C (think type-based aliasing on steroids).
Don't get me wrong, it's good design to nicely package these in unsafe code, but if your language can craft pointers and load/store from them, your spec will have to have UB (or boundcheck all loads and stores).
- DSMan195276 8y ago> the rules for UB in unsafe code are going to be more complicated than C This is one of the biggest issues I have with Rust, personally. The interaction between safe and unsafe Rust is not well defined, making it largely impossible to write 'correct' unsafe Rust that isn't broken in some weird situation, or won't ever get broken in later versions of the compiler. And since the Rust compiler has even more information then the C compiler does, it can theoretically make much crazier optimizations then it is doing right now that could break your code down the line. Like you mentioned, if it goes down that route it'll be like the strict-aliasing situation in C but times 10.
- jacobush 8y agoI wonder if it would help if there were different rules for un-safe Rust and safe Rust? Or from a more pragmatic point of view, if one could compile un-safe Rust similarly to "optimisations off" in C compilers. No aggressive optimisation, only straight forward translation. While Rust code marked safe could be compiled with the most insane optimisations, and still be ... safe. If not, I think people concerned about such things, might opt to write the unsafe parts on C (a known quantity) and the safe parts in Rust.
- steveklabnik 8y agoThat won’t work, because safe rust optimizes around rules unsafe is expected to uphold. Even a “straightforward translation” of the unsafe could still easily break invariants safe code expects. All this stuff is why we’re working so hard on formalizing unsafe! Your parent is right that it’s a bit fuzzy right now, but in the future, we hope that it’ll be way nicer than other unsafe languages. There’s some tooling ideas...
- jacobush 8y agoThat's interesting to hear, both things.
- hsivonen 8y agoA crate that I wrote, encoding_rs uses unsafe for performance purposes (probably a bit more than absolutely necessary). I'd be very unhappy if unsafe compiled to slower code. The unsafe bits intermingle with safe Rust to such a degree that having to write them in C would make me very unhappy. For the curious, the performance uses of unsafe in encoding_rs are roughly in these categories: - Omitting Unicode correctness checks (i.e. asserting that output is correct without having the standard library re-check; Unicode correctness is part of the core competence of the crate). - Viewing buffers of u8 or u16 as buffers of usize. - Viewing buffers of u8 or u16 as SIMD register-sized units. - Omitting bound checks where the compiler fails to elide them and it matters for performance, especially where the performance difference matters for competitiveness with C++. - Reinterpreting SIMD registers in a different lane configuration. (Exposes endianness but otherwise actually safe.) - Calling intrinsics that don't really have anything unsafe about them except that Rust makes intrinsics categorically unsafe instead of deciding on a case by case basis if they need to be unsafe. Of these, viewing buffers as buffers of ALU or SIMD register-sized units are the only cases that come near strict aliasing and could be trouble if the compiler felt eligible to reorder writes of (in the C sense) incompatible types relative to each other on the assumption that buffers of different types are disjoint.
- jacobush 8y agoToday I learned that Rust the language, if not the current implementation, could conceivably treat (some) intrinsics as safe.
- zokier 8y ago> The interaction between safe and unsafe Rust is not well defined Not contesting the claim, but what in the interaction specifically is not well defined?
- steveklabnik 8y agoThe interaction is well defined in the sense of “unsafe leta you do these things” but specifically, the rules about what invariants unsafe is required to uphold are not super well defined. The overall shape is there, but we’re not at an ISO standard level of definition. It’s an active area of work and research.
- clarry 8y ago> Some UB in C is largely regarded as a bad idea, such as signed overflow. I don't see why it's so bad. I've never really seen a legitimate use for signed overflow, and if it happens, the code is likely buggy anyway. "I don't know how to properly check overflows so I'm just going to look and see if the number has wrapped" isn't really a good excuse, even if a few people fall for that trap. If anything, I'd rather see a simple, standard way for checking arithmetic introduced.
- kqr 8y agoIt sounds like you are under the impression that UB simply means you can't trust signed integers to wrap. Unfortunately, it is worse than that; under surprisingly normal-looking conditions, it is not unheard of that the compiler optimises an interation check away and replaces it with constant true or false, depending on what makes the underlying internal represenation neater. That's way beyond "can't do X"; it's "the meaning of your program suddenly ceases to exist".