3 ms·
> resulting in an incorrect code. Incorrect with respect to an assumption furnished where? Your sibling comment mentions RFCs—is this behavior tied to some kin
by NoTeslaThrow 1y ago
> resulting in an incorrect code.
Incorrect with respect to an assumption furnished where? Your sibling comment mentions RFCs—is this behavior tied to some kind of documented expectation?
> A simpler example is `Option<NonZeroU8>`, the compiler assumes that `NonZeroU8` can never contain 0, thus it can use 0 as value for `None`. Now, if you take a reference to the inner `NonZeroU8` stored in `Some` and write 0 to it, you changed `Some` to `None`, while other optimizations may rely on the assumption that references to the content of `Some` can not flip the enum variant to `None`.
That seems to be the intended behavior, unless I'm reading incorrectly. Why else would you write a 0 to it? Also, does this not require using the `unsafe` keyword? So is tricking the compiler into producing the behavior you described not the expected and intended behavior?
- newpavlov 1y ago>Incorrect with respect to an assumption furnished where? In the definition of the `NonZeroU8` type. Or in a more practical terms, in LLVM, when we generate LLVM IR we communicate this property to LLVM and it in turn uses it to apply optimizations to our code. >Also, does this not require using the `unsafe` keyword? Yes, it requires `unsafe` and the point is that writing 0 to `NonZeroU8` is UB since it breaks the locality principle critical for correctness of optimizations. Applying just one incorrect (because of the broken assumption) optimization together with numerous other (correct) optimizations can easily lead to very surprising results, which are practically impossible to predict and debug. This is why it's considered such anathema to have UB in code, since having UB in one place may completely break code somewhere far away.
- fc417fc802 1y agoIt's not intended in that the compiler may have optimized based on the assumption that you have now gone and violated via an unsafe block. Just as in C that would produce undefined behavior in that there's no telling what consequences the optimization might have. The lack of a formal specification isn't relevant.
- lmm 1y ago> is tricking the compiler into producing the behavior you described not the expected and intended behavior? It might be what that programmer intended and expected, but they should not expect it. E.g. the current compiler might check for 0, and a future more optimized compiler might optimize out that check (because it knows the Option is not None) and then e.g. perform an out-of-bounds array access (if you were using that NonZeroU8 as an index into some kind of 1-based array).