Hacker News new | ask | show | jobs
by jstimpfle 21 days ago
UB is a runtime property. As far as you can statically verify some code parts, you can see UB at compile time, but the point of UB is exactly that it is about stuff you can't predict, or that is hard to predict as a compiler.

Now why you can cook up trivial artificial examples where a compiler will remove some code sections based on statically detected UB, instead of printing an error, you have to ask the compiler authors.

> The semantics are well-defined in both modes.

So they're not the same? So the behaviour is not uniquely defined by the source code alone, but is actually _very_ different based on compile mode? Between two modes whose point was never to have different semantics, but to have the _same_ semantics while being debuggable vs being fast?

> You can predict exactly what will happen in either case. In C, the semantics are not defined at all, you can't predict what will happen and it's allowed to change between compilations of the same source.

You can make the same "predictability" argument for C, you can easily write a compiler that has semantics exactly laid out. Case in point: -fwrapv. Case in point: UBSAN.

1 comments

You can write a C compiler with exactly laid out well-defined semantics. You can't assume those semantics hold for C-the-language, because it doesn't define those semantics. UB is a property of the language, not just of a given compiler. The Rust reference defines the semantics of the safe subset of Rust without any UB, so any compliant Rust compiler won't have UB in that subset. The reference also defines the guarantees which the programmer must uphold within `unsafe` blocks to avoid UB, as long as those are upheld there's no UB at all.
I understand that. It makes no practical difference. 99,99% of my additions don't rely on signed overflow for example, and if I'd ever need it there are ways to get just it.

Or tell me how you write a Rust program differently given that signed overflow is apparently defined? I bet you write it exactly the same way, and you get pretty much the same behaviour in practice. And we're even only debating actual overflow situations, meaning there is a bug whatever the compiled behaviour is.

C the language doesn't even guarantee that the machine has native integers with 8, 16, 32, 64 bits etc, that a cacheline is 64 bits, that a page is 4K, and here I am, writing programs for exactly that.