An example in the release notes on Operator Precedence with a lot of parentheses inspired me to check whether I know all the side effects of the defined order of operations.
One of the quirks of the integer overflow UB I had not realized before is that, since it is observed by the compiler operation-wise, this UB (and the transformations the compiler does because of it) is sensitive to the order in which arithmetic is performed. In particular, I would argue that, in the status quo, omitting parentheses in a chain of additions has implicit control flow.
Take a look at this example, keeping in mind that addition is left-associative. In the compare_good function, both a + b and c + d are evaluated first, so the compiler sees the guarantee that they fit into i32. In compare_bad, a - 10 and c - 10 are evaluated first, so there is no such guarantee, and removing -10 might cause an extra overflow on either side of the less operator. Even the explicit evaluation (and assertion) in compare_ugly cannot resurrect the optimization since dead code elimination stole this information way earlier.
Unfortunately, the compilers relying on SSO have to do operation-wise UB, and not make just the results of the whole associative operation UB on overflow. Nonetheless, the optimizations would be more consistent if only the final result were checked (or assumed). For now, we might want to just put our constants at the very right in arithmetic for better optimizations sometimes.
What do you think about this?