The problem with UB in the C like languages is that it is grossly overused.
What happens when you go out of bounds? Who knows! Time for UB!
What happens when multiply an hummer overflows? Everyone! There is no reason for it to be UB
In a way, this being written by a UB researcher is kind of unconvincing (a researcher thinks his chosen research topic deserves a better reputation!), but maybe it is more analogous to corruption researcher saying corruption can be beneficial.
I didn’t like some of the examples, but I agree with the core point, in moderation. UB exists because proving some things is not tractable. The simplest example: accessing a pointer after it has been passed to free() is UB. How could this be anything else? The only two sensible defined behaviours are that the access would prolong the lifetime of the object and so you’d see its prior state, or that it would trap (or a non-deterministic choice between the two). That imposes a huge penalty on the memory allocator: it can’t recycle an address until it’s proven that there are no pointers left to it. In a non-CHERI system, where pointers are indistinguishable from integers and can be materialised from thin air, that’s not even possible.
Or the simpler case: access past the end of an array is UB. Again, making this defined behaviour would require that the compiler carries the bounds around with any pointer (since C doesn’t know the difference between pointers to single objects and pointers to arrays), or having separate pointer-to-array, pointer-to-member, and pointer-to-object types and explicit bounds checks.
The article talks about UB being required for hoisting bounds checks. I don’t believe that’s actually the case. It’s true only because of a language requirement that traps / exceptions happen at a specific point. If the guarantee is that a trap may be raised from any point in program order after which the contract violation becomes deterministically reachable, then you don’t need UB: this would let you hoist bounds checks out of loops and trap at the start, though the programmer model could be quite exciting. You’d also need some mechanism for limiting the scope of propagation of contract failures.