X-Git-Url: https://git.ralfj.de/web.git/blobdiff_plain/cb8b218a295d24625cdc7ecfeb9c1580cb9ff3b9..c9ee2a442bf0b3fc7379e697925381862bfdc849:/personal/_posts/2020-07-15-unused-data.md?ds=sidebyside diff --git a/personal/_posts/2020-07-15-unused-data.md b/personal/_posts/2020-07-15-unused-data.md index afdfff9..b9b51b1 100644 --- a/personal/_posts/2020-07-15-unused-data.md +++ b/personal/_posts/2020-07-15-unused-data.md @@ -30,6 +30,8 @@ fn example(b: bool) -> i32 { I hope it is not very surprising that calling `example` on, e.g., `3` transmuted to `bool` is Undefined Behavior (UB). When compiling `if`, the compiler assumes that `0` and `1` are the only possible values; there is no saying what could go wrong when that assumption is violated. +(This is a compiler-understood *validity invariant* that is fixed in the language specification, which is very different from a user-defined *safety invariant*. +See [this earlier post]({% post_url 2018-08-22-two-kinds-of-invariants %}) for more details on that distinction.) What is less obvious is why calling `example` on `3` is UB even when there is no such `if` being executed. To understand why that is important, let us consider the following example: @@ -53,7 +55,7 @@ That transformation can be used to turn our `example` function into the followin {% highlight rust %} fn example(b: bool, num: u32) -> i32 { let mut acc = 0; - let incr = if b { 42 } else { 23 } + let incr = if b { 42 } else { 23 }; for _i in 0..num { acc += incr; }