I think you’re running into undefined behavior here - from kristoff-it on the old zig reddit:
Absolutely not. unreachable marks that a code path is impossible to trigger. In safe modes you will get a panic if you got it wrong, while in unsafe modes (ReleaseFast, ReleaseSmall) you will potentially get a misbehaving program.
Your point is well taken though - it’s strange that in the documentation it says that it’s equivalent to unreachable. @kristoff any thoughts?
I tried it in godbolt
It indeed seems to produce different code, both in debug and release. orelse unreachable produces more code in debug, which I guess makes sense given that .? is a more specific concept.
However llvm seems to be better at optimizing orelse unreachable
But I personally think it’s fine that they behave differently, given that it’s only noticable within the bounds of undefined behavior.
It’s equivalent when the behavior is defined - we’re in UB land here, so anything goes, including “maybe break the program and maybe don’t”. x.? and x catch unreachable will likely be lowered by the compiler in slightly different (but semantically equivalent provided x is non-null) ways, allowing the UB to behave differently here.